Does using a document fragment really improve performance?

后端 未结 7 1284
臣服心动
臣服心动 2020-11-30 01:57

I\'ve got a doubt regarding performance in JS.

Say, I\'ve got the next code:

var divContainer = document.createElement(\"div\"); divContainer.id=\"co         


        
相关标签:
7条回答
  • 2020-11-30 02:11

    Document Fragment is much faster when it is used to insert a set of elements in multiple places. Most answers here point out its un-utility, but this is to demonstrate its strength.

    Lets take an example.

    Say we need to append 20 divs in 10 elements with class container.

    Without:

    var elements = [];
    for(var i=20; i--;) elements.push(document.createElement("div"));
    
    var e = document.getElementsByClassName("container");
    for(var i=e.length; i--;) {
      for(var j=20; j--;) e[i].appendChild(elements[j].cloneNode(true));
    }
    


    With:

    var frag = document.createDocumentFragment();
    for(var i=20; i--;) frag.appendChild(document.createElement("div"));
    
    var e = document.getElementsByClassName("container");
    for(var i=e.length; i--;) e[i].appendChild(frag.cloneNode(true));
    

    For me using a document fragment turns out to be 16 times faster on Chrome 48.

    Test on JsPerf

    0 讨论(0)
  • 2020-11-30 02:11

    Normally you'd want to use a fragment to avoid reflows (repainting the page). A good case would be if you were looping over something and appending within the loop, however, I think modern browsers optimize for this already.

    I set up a jsPerf to illustrate a good example of when to use a fragment here. You'll notice in Chrome that there is hardly a difference (modern optimization at work, I presume), however, in IE7 I get .08 ops/sec without the fragment, 3.28 ops/sec with a fragment.

    So, if you're looping over a large data set and appending A LOT of elements use a fragment instead so you only have one reflow. If you're only appending to the dom a few times or you're only targetting modern browsers it isn't necessary.

    0 讨论(0)
  • 2020-11-30 02:24

    I've written a jspref to test this and it appears the node fragment is 2.34 % faster

    http://jsperf.com/document-fragment-test-peluchetti

    0 讨论(0)
  • 2020-11-30 02:25

    I had the exact same question as the OP, and after reading through all the answers and the comments, it didn't seem like anybody really understood what the OP was asking.

    I took a cue from the test Nicola Peluchetti posted and modified it a bit.

    Instead of appending elements to a <div> and then appending to the documentFragment, the fragment test gets the elements appended directly to it (the documentFragment) instead of first to the <div>. Also, to avoid any hidden overhead costs, both tests begin by creating both the <div> container and the documentFragment, while each test only utilizes one or the other.

    I took the original question to be, basically, is it faster to do a single append of nodes using a <div> or a documentFragment as the container?

    Looks like using a <div> is faster, at least on Chrome 49.

    http://jsperf.com/document-fragment-test-peluchetti/39

    The only use case I can think of for documentFragment (at the moment) is if it takes less memory (which could be negligible), or if you have a bunch of sibling nodes to append which you don't want to put into a "container" element. The documentFragment is like a wrapper which dissolves leaving only its contents.

    0 讨论(0)
  • 2020-11-30 02:32

    <!DOCTYPE html>
    <html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    </head>
    <body>
    <div ms-controller='for1'>
        <ul>
    
        </ul>
    </div>
    
    <script>
        var ul = document.querySelector('ul');
        console.time('no fragment');
        for(var i=0;i<1000000;i++){
            var li = document.createElement('li');
            li.innerText = i;
    
            ul.appendChild(li);
        }
        console.timeEnd('no fragment');
    
        console.time('has fragment');;
        var frg = document.createDocumentFragment()
        for(var i=0;i<1000000;i++){
            var li = document.createElement('li');
            li.innerText = i+'fragment';
            frg.appendChild(li);
    
        }
        ul.appendChild(frg)
        console.timeEnd('has fragment');
    </script>
    </body>
    </html>

    the result is no fragment: 1615.278ms testFragment.html:36 has fragment: 2908.286ms

    so,no Fragment is more faster. I think the reason is the chrome had do some thing.

    0 讨论(0)
  • 2020-11-30 02:32

    The jsperf from wolfram77 contains an additional for loop in the non fragment example which is the main cause for the performance difference, not the DocumentFragment. By removing this additional for loop you can achieve the same result but the performance is completely different:

    Example on jsperf.com

    So I still don't see a performance benefit on the scripting part but there might be one in the browser when it has to repaint for each appended element.

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