Why is documentFragment no faster than repeated DOM access?

前端 未结 2 2148
忘掉有多难
忘掉有多难 2021-02-15 01:56

I was always under the impression that rather than touching the DOM repeatedly, for performance reasons, we should use a documentFragment to append multiple element

相关标签:
2条回答
  • 2021-02-15 02:36

    Well actually your test code just insert nodes and do not alter their content or CSS which would in fact force the rendering engine to a reflow.

    I have prepared 3 tests to demonstrate this dramatic difference.

    1. Simple DOM modificiation resulting Layout Trashing
    2. Simple DOM modificiation through window.requestAnimationFrame()
    3. Virtual DOM modification through document.createDocumentFragment()

    Notes:

    • You might like to test on full screen.
    • In Firefox I have obtained even more dramatic results.

    // 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>

    0 讨论(0)
  • 2021-02-15 02:47

    Sorry... Due to the 30000 character limit in the answers and the length of the previous one i have to place another one as an extension to my previous answer.

    I guess everybody's heard that direct DOM access is no good... Yes that's what i had always been told and so believed in the correctness of the virtual DOM approach. Though i hadn't quite understood the fact that while both the DOM and vDOM are represented on the memory, how come one is faster than the other? Actually streching my test further i have come to believe that the real bottle neck boils down to the JS engine performance if you update the DOM properly.

    Now lets imagine the case of having 1000 divs to be updated repeatedly on background-color and height CSS properties.

    If you do this directly on DOM elements all you have to do is to keep a nodeList of these elements and simply alter their style.backgroundColor and style.heigth properties.

    If you do this by a document fragment you have the apparent benefit of not touching the DOM multiple times, instead first you have to

    1. clone the parent container of the 1000 div elements.
    2. access the nodeList containing the divs like parent.children
    3. perform necessary alterations on each div element,
    4. create a document fragment
    5. re-clone the previously cloned (step 1) parent container element and append it to a document fragment (or alternatively you may chose to clone the divs' container from the DOM if you need the fresh ones but this way or that way for each modification you have to clone them)
    6. append the document fragment to the parent of div container in the DOM and remove the old div container. Basically a Node.replaceChild operation.

    In fact for this test we don't need a document fragment since we are not creating new nodes but just updating the already existing ones. So we can skip the step 4 and at step 5 we can directly use the cloned copy of our divs container as a source to our replaceChild operation.

    How to update DOM properly..? Definitely asynchronously. So as for the previous example if you move the direct update portion to an asynchronous timeline like setTimeout(_ => renderDirect(),0) it will be the fastest among all. But then repeatedly updating the dome can be a little tricky.

    One way to achieve this is to repedeatly feed a setTimeout(_ => renderDirect(),0) with our DOM updates like.

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

    In the above case the performance of the JS engine is very material on the results. If our code is too light, than multiple cycles will stack up on a single DOM update and we will observe only a few of them. In this particular case, we got to see only like 9 of the 50 updates.

    So delaying each turn further might be a good idea. So how about;

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

    Well this is much better, I've got 22 of the 50 updates actually painted on my screen. So it happens to be, if the delay is chosen to be long enough you'll have all the frames painted. But how much long is a problem. Since if it's too long you have idle time for your rendering engine and it resembles slow DOM update. So for this particular test, it turns out to be something like 29-30ms ish... is the optimal value to observe 50 separate DOM updates of all 1000 divs in 1400 ms. Well at least on my desktop with Chrome. You may observe something entirely different depending on the hardware or the browser.

    So the setTimeout resolution doesn't look very promising to me. We have to automate this job. Lucky us, we have the right tool for this job. rAF to help again. I have come up with a helper function to abuse the rAF (requestAnimationFrame). We will update the 1000 divs all at once, in one go, by directly accessing the DOM at the next available animation frame. And... while we are still in the asynchronous timeline we will request another animation frame from within the currently executing callback. So another rAF is called from the callback of the rAF recursively. I named this function looper

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

    well it's a bit of an ES6 code. So let me translate it into classing JS.

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

    Now everything should be automated.. It seems pretty cool and done in 1385ms.

    So since now we are a little more knowledgeable we may play with the code.

    // 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>

    So the tests look like direct access through rAF is better than cloning and working on the clone and replacing the old one with it. Particularly when a huge DOM chunk is replaced it seems to me that the GC (Garbage Collect) task gets involved in the middle of the job and things get a little sticky. I am not sure how it can be eliminated. Your ideas are most welcome.

    0 讨论(0)
提交回复
热议问题