为什么documentFragment不比重复的DOM访问快?

时间:2017-04-13 20:51:23

标签: javascript performance dom

我一直认为,不是为了性能原因而反复触摸DOM,我们应该使用documentFragment附加多个元素,然后将片段附加到文档中一次,而不是仅重复将新元素逐个添加到DOM中。

我一直在尝试使用Chrome的开发工具来分析这两种方法,使用此测试页:

<button id="addRows">Add rows</button>
<table id="myTable"></table>

测试1使用此代码向表中附加50000个新行:

let addRows = document.getElementById('addRows');
addRows.addEventListener('click', function () {
    for (let x = 0; x < 50000; x += 1) {
        let table = document.getElementById('myTable'),
            row = document.createElement('tr'),
            cell = document.createElement('td'),
            cell1 = cell.cloneNode(),
            cell2 = cell.cloneNode(),
            cell3 = cell.cloneNode();

        cell1.textContent = 'A';
        cell2.textContent = 'B';
        cell3.textContent = 'C';

        row.appendChild(cell1);
        row.appendChild(cell2);
        row.appendChild(cell3);
        table.appendChild(row);
    }
});

在Chrome的时间轴工具中录制时单击按钮会产生以下输出:

Repeated DOM interaction

测试2使用此代码:

let addRows = document.getElementById('addRows');
addRows.addEventListener('click', function () {
    let table = document.getElementById('myTable'),
        cell = document.createElement('td'),
        docFragment = document.createDocumentFragment();

    for (let x = 0; x < 50000; x += 1) {
        let row = document.createElement('tr'),
            cell1 = cell.cloneNode(),
            cell2 = cell.cloneNode(),
            cell3 = cell.cloneNode();

        cell1.textContent = 'A';
        cell2.textContent = 'B';
        cell3.textContent = 'C';

        row.appendChild(cell1);
        row.appendChild(cell2);
        row.appendChild(cell3);

        docFragment.appendChild(row);
    }

    table.appendChild(docFragment);
});

这有如下性能配置文件:

enter image description here

第二个,据说比第一个更快的替代方案,实际上需要更长的时间才能运行!我已经多次运行这些测试,有时第二种方法稍微快一点,有时,正如这些图像显示的那样,第二种方法稍微慢一些,但两种方法之间没有任何显着差异。

这里发生了什么?浏览器是否已经过如此优化,现在又不再有差别了?我是否错误地使用了分析工具?

我在Windows 10上,使用Chrome 57.0.2987.133

3 个答案:

答案 0 :(得分:5)

实际上,您的测试代码只是插入节点而不会改变其内容或CSS,这实际上会强制渲染引擎进行重排。

我准备了3个测试来证明这种显着的差异。

  1. 简单DOM修改导致布局删除
  2. 通过window.requestAnimationFrame()
  3. 进行简单的DOM修改
  4. 通过document.createDocumentFragment()
  5. 进行虚拟DOM修改

    备注:

    • 您可能希望全屏测试。
    • 在Firefox中,我获得了更加生动的结果。

    // Resets the divs
    function resetLayout() {
      divs = document.querySelectorAll('div');
      speed.textContent = "Resetting Layout...";
      setTimeout(function() {
                   each.call(divs, function(div) {
                                     div.style.height = '';
                                     div.offsetTop;
                                   });
                   speed.textContent = "";
                 }, 16);
    }
    // print the result
    function renderSpeed(ms) {
      speed.textContent = ms + 'ms';
    }
    
    var divs        = document.querySelectorAll('div'),
        raf         = window.requestAnimationFrame,
        each        = Array.prototype.forEach,
        isAfterVdom = false,
        start       = 0;
    
    // Reset the Layout
    
    reset.onclick = resetLayout;
    
    // Direct DOM Access
    
    direct.onclick = function() {
                       isAfterVdom && (divs = document.querySelectorAll('div'), isAfterVdom = false);
                       start = performance.now();
    
                       each.call(divs, function(div) {
                       var width = div.clientWidth;
                       div.style.height = ~~(Math.random()*2*width+6) + 'px';
                       div.style.backgroundColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
                     });
    
                       // Render result
                       renderSpeed(performance.now() - start);
                     };
    
    // Access DOM at the next frame by requestAnimationFrame
    
    rAF.onclick = function() {
                    isAfterVdom && (divs = document.querySelectorAll('div'), isAfterVdom = false);
                    start = performance.now();
    
                    each.call(divs, function(div) {
                                      var width = div.clientWidth;
                                      // Schedule the write operation to be run in the next frame.
                                      raf(function() {
                                            div.style.height = ~~(Math.random()*2*width+6) + 'px';
                                            div.style.backgroundColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
                                          });
                                    });
                   // Render result
                   raf(function() {
                         renderSpeed(performance.now() - start);
                       });
                 };
    
    // Update the vDOM and access DOM just once by rAF
    
    vdom.onclick = function() {
                     var sectCl = divCompartment.cloneNode(true),
                         divsCl = sectCl.querySelectorAll('div'),
                         dFrag  = document.createDocumentFragment(),
                         width  = divCompartment.querySelector('div').clientWidth;
                     
                     isAfterVdom = true;
                     end = 0;
                     start  = performance.now();
                     each.call(divsCl, function(div) {
                                         div.style.height = ~~(Math.random()*2*width+6) + 'px';
                                         div.style.backgroundColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
                                       });
                     dFrag.appendChild(sectCl);
                     divCompartment.parentNode.replaceChild(dFrag, divCompartment);
                     // Render result
                     renderSpeed(performance.now() - start);
                   };
    html {
      font: 14px Helvetica, sans-serif;
      background: black;
      color: white;
    }
    
    * {
      box-sizing: border-box;
      margin-bottom: 1rem;
    }
    
    h1 {
      font-size: 2em;
      //word-break: break-word;
      -webkit-hyphens: auto;
    }
    
    button {
      background-color: white;
    }
    
    div {
      display: inline-block;
      width: 5%;
      margin: 3px;
      background: white;
      border: solid 2px white;
      border-radius: 10px
    }
    
    section {
      overflow: hidden;
    }
    
    #speed {
      font-size: 2.4em;
    }
    <body>
      <h1>Updating 1000 DOM Nodes</h1>
      <section>
        <button id="reset">Reset Layout</button>
        <button id="direct">Update Directly</button>
        <button id="rAF">Update by rAF</button>
        <button id="vdom">Update by vDOM</button>
        <section id="speed"></section>
        <section id="divCompartment">
          <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        </section>
    </body>

答案 1 :(得分:4)

抱歉......由于答案中的30000个字符限制以及前一个字符的长度,我必须将另一个作为我之前答案的扩展名。

我想每个人都听说直接DOM访问并不好......是的,这就是我一直被告知的,因此相信虚拟DOM方法的正确性。虽然我还没有完全理解这样一个事实:虽然DOM和vDOM都在内存中表示,但是为什么一个比另一个快?实际上拉伸我的测试我已经开始相信,如果你正确地更新DOM,真正的瓶颈归结为JS引擎性能。

现在让我们想象一下在背景颜色和高度CSS属性上重复更新1000个div的情况。

如果直接在DOM元素上执行此操作,您所要做的就是保留这些元素的nodeList,只需更改其style.backgroundColorstyle.heigth属性。

如果您通过文档片段执行此操作,您可以获得多次不触及DOM的明显好处,而不是首先必须

  1. 克隆1000个div元素的父容器。
  2. 访问包含像parent.children
  3. 这样的div的nodeList
  4. 对每个div元素执行必要的更改
  5. 创建文档片段
  6. 重新克隆先前克隆的(步骤1)父容器元素并将其附加到文档片段(或者如果您需要新的容器,您可以选择从DOM克隆div的容器,但这样或那样对于每个修改,你必须克隆它们)
  7. 将文档片段附加到DOM中div容器的父级,并删除旧的div容器。基本上是Node.replaceChild操作。
  8. 实际上,对于此测试,我们不需要文档片段,因为我们不是创建新节点而只是更新已存在的节点。所以我们可以跳过第4步,在第5步,我们可以直接使用divs容器的克隆副本作为我们的replaceChild操作的源。

    如何正确更新DOM ..?绝对是异步的。因此,对于上一个示例,如果将直接更新部分移动到异步时间轴(如setTimeout(_ => renderDirect(),0)),它将是最快的。但是反复更新圆顶可能有点棘手。

    实现这一目标的一种方法是使用我们的DOM更新来重复提供setTimeout(_ => renderDirect(),0)

    for (var i = 0; i < cnt; i++) setTimeout(_ => renderDirect(divs,width),0);
    

    在上面的例子中,JS引擎的性能对结果非常重要。如果我们的代码太轻,那么多个循环将叠加在单个DOM更新上,我们将只观察其中的一些。在这种特殊情况下,我们只能看到50个更新中的9个。

    enter image description here

    因此,进一步延迟每一轮可能是一个好主意。那怎么样;

    for (var i = 0; i < cnt; i++) setTimeout(_ => renderDirect(divs,width),i*17);
    

    enter image description here

    嗯,这要好得多,我在屏幕上实际绘制的50个更新中有22个。所以碰巧的是,如果选择的延迟足够长,你就会画出所有画面。但问题是多长时间。因为如果它太长,你的渲染引擎有空闲时间,它类似于缓慢的DOM更新。因此,对于这个特定的测试,结果是29-30ms ish ...是在1400毫秒内观察所有1000个div的50个独立DOM更新的最佳值。至少在我的Chrome桌面上。根据硬件或浏览器的不同,您可能会发现完全不同的东西。

    enter image description here

    所以setTimeout分辨率对我来说并不是很有希望。我们必须自动完成这项工作。幸运的是,我们有适合这项工作的工具。 rAF再次帮助。我想出了一个帮助函数来滥用rAF(requestAnimationFrame)。我们将在下一个可用的动画帧中直接访问DOM,一次更新所有1000个div。并且......当我们仍在异步时间轴中时,我们将在当前执行的回调中请求另一个动画帧。因此,递归地从rAF的回调中调用另一个rAF。我将此函数命名为looper

    var looper = n => n && raf(_ => (renderDirect(divs, width),looper(--n)));
    

    这是一个ES6代码。所以让我把它翻译成JS分类。

    function looper(n){
      if (n !== 0) {
        window.requestAnimationFrame(function(){
                                       renderDirect(divs,width);
                                     });
        looper(n-1);
      }
    }
    

    现在一切都应该自动化了。看起来非常酷,并且在1385ms完成。

    enter image description here

    因此,从现在开始,我们可以更好地了解代码。

    // Resets the divs
    function resetLayout() {
      divs = document.querySelectorAll('div');
      speed.textContent = "Resetting Layout...";
      setTimeout(function() {
                   each.call(divs, function(div) {
                                     div.style.height = '';
                                     div.backcgoundColor = '';
                                   });
                   speed.textContent = "";
                 }, 16);
    }
    // print the result
    function renderSpeed(ms) {
      speed.textContent = ms + 'ms';
    }
    
    function renderDirect(divs,width){
      each.call(divs, function(div) {
                        div.style.height = ~~(Math.random()*2*width+6) + 'px';
                        div.style.backgroundColor = '#' + Math.random().toString(16).substr(-6);
                      });
    
      // Render result
      renderSpeed(performance.now() - start);
    }
    
    function renderByVDOM(sct,prt,wdt){
      var //dFrag = document.createDocumentFragment();
          divs  = sct.children;
      each.call(divs, function(div) {
                        div.style.height = ~~(Math.random()*2*wdt+6) + 'px';
                        div.style.backgroundColor = '#' + Math.random().toString(16).substr(-6);
                      });
      //dFrag.appendChild(sct);
      prt.replaceChild(sct, divCompartment);
      // Render result
      renderSpeed(performance.now() - start);
    }
    
    var divs        = document.querySelectorAll('div'),
        width       = divs[1].clientWidth;
        raf         = window.requestAnimationFrame,
        each        = Array.prototype.forEach,
        isAfterVdom = false,
        start       = 0,
        cnt         = 50;
    
    // Reset the Layout
    
    reset.onclick = resetLayout;
    
    // Direct DOM Access
    
    direct.onclick = function() {
                       var looper = n => n && raf(_ => (renderDirect(divs, width),looper(--n)));
                       isAfterVdom && (divs = document.querySelectorAll('div'), isAfterVdom = false);
                       start = performance.now();
                       //for (var i = 0; i < cnt; i++) setTimeout(_ => renderDirect(divs,width),i*29);
                       looper(cnt);
                     };
    
    // Update the vDOM and access DOM just once by rAF
    
    vdom.onclick = function() {
                     var sectCl = divCompartment.cloneNode(true),
                         parent = divCompartment.parentNode,
                         looper = n => n && raf(_ => (renderByVDOM(sectCl.cloneNode(true), parent, width),looper(--n)));
                     
                     isAfterVdom = true;
                     start  = performance.now();
                     looper(cnt);
                   };
    html {
      font: 14px Helvetica, sans-serif;
      background: black;
      color: white;
    }
    
    * {
      box-sizing: border-box;
      margin-bottom: 1rem;
    }
    
    h1 {
      font-size: 2em;
      -webkit-hyphens: auto;
    }
    
    button {
      background-color: white;
    }
    
    div {
      display: inline-block;
      width: 5%;
      margin: 3px;
      background: white;
      border: solid 2px white;
      border-radius: 10px
    }
    
    section {
      overflow: hidden;
    }
    
    #speed {
      font-size: 2.4em;
    }
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <title>repl.it</title>
        <link href="index.css" rel="stylesheet" type="text/css" />
        <script src="index.js" async></script>
      </head>
      <body>
      <h1>Updating 1000 DOM Nodes</h1>
      <section>
        <button id="reset">Reset Layout</button>
        <button id="direct">Update Directly</button>
        <button id="vdom">Update by vDOM</button>
        <section id="speed"></section>
        <section id="divCompartment">
          <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
        </section>
      </section>
    </body>
    </html>

    所以测试看起来像通过rAF直接访问比克隆和处理克隆并用它替换旧的更好。特别是当一个巨大的DOM块被替换时,在我看来GC(垃圾收集)任务涉及到工作中间并且事情变得有点棘手。我不确定如何消除它。您的想法非常受欢迎。

答案 2 :(得分:0)

我不确定如何准确地解释您的探查器结果,但通过benchmark.js测试显示Chrome中的第二个选项更快:https://jsbench.me/awj1gwhk9i/1

在FF中也更快(虽然差异稍小)