0

First of all, this is not the same as this question, although you may think it is as first glance: Does using a document fragment really improve performance?

See: this js fiddle https://jsperf.com/fragment-no-clone

If you are creating a bunch of new nodes in a loop with the intention of appending them to the DOM, in my MIND it is way faster to first create a fragment, append those elements to the fragment, and then append the fragment to the DOM after everything is set up. (as opposed to creating an element, append to DOM, create the next element, append to DOM, one after the other)

Here is a bit of code just to illustrate what I mean:

Using a Fragment

let fragment = document.createDocumentFragment();
for (var i = 0; i < 100; i++) {
  let element = document.createElement('div');
  fragment.appendChild(element);
}

document.body.appendChild(fragment);

Not using a Fragment

for (var i = 0; i < 100; i++) {
  let element = document.createElement('div');
  document.body.appendChild(element);
}

The reason why I think the fragment should be faster is because my understanding of how browsers work: If I'm just appending elements one after the other immediately then the browser has to do way more painting and calculating, whereas if I set it up nicely in a fragment and then append everything all at once, the browser only has to paint/calculate once

HOWEVER.

I am not really seeing that kind of performance gain in reality. Testing Chrome/Safari on that fiddle the difference is negligible, and while in Firefox there is a small boost in favour of using a fragment, it's nothing huge.

So what's happening under the hood? Is my understanding totally flawed?

Rose Robertson
  • 1,236
  • 7
  • 14
  • 1
    `See: this js fiddle https://jsperf.com/fragment-no-clone` a document fragment is nearly twice as fast for me on Firefox. – VLAZ Sep 27 '18 at 03:43
  • @vlaz ooo nice so maybe my gut is correct after all – Rose Robertson Sep 27 '18 at 03:46
  • what I'm seeing is that NOT using a fragment is faster in chrome/safari but only by a tiny bit, not enough to really mean anything. They're basically neck-and-neck. – Rose Robertson Sep 27 '18 at 03:51
  • 1
    Just to let you know - I wrote that comment as I started reading the question. I then ran the test in Chrome and finished reading the question. Had to wait for a bit, as Chrome hadn't finished. In chrome, the difference was pretty small and even though the second approach was faster, that was by around a percent. BOTH were a lot slower than FF, though - in FF using the fragment the speed reported was ~450 ops per second, the direct approach was ~200 ops/sec. In Chrome, by comparison both were ~120-130. – VLAZ Sep 27 '18 at 03:52
  • 1
    I think the test would show different results for complex DOM nodes being inserted - what I mean is nodes that will have CSS styles applied to them that could potentially have to re-fit items in containers which would be a more complex reflow each time. A document fragment should minimise the impact of these. – VLAZ Sep 27 '18 at 03:55
  • @vlaz Oh really good point that I hadn't thought of, thank you. That's probably the answer. Maybe I'll try putting together a test to confirm! – Rose Robertson Sep 27 '18 at 03:57
  • Actually, I was looking at that other question you mentioned and noticed something in the comments to the accepted answer: `he jsPerf test here does not incorporate page reflows` I suspected that might be the case - I didn't think it actually puts your data in some DOM that's displayed. If it's in something like an iframe that is hidden, it wouldn't reflow. So, perhaps a more accurate test is to make an HTML page and re-try both approaches using the developer performance measuring tools. – VLAZ Sep 27 '18 at 04:04
  • The DOM is just a js object. So your two tests should indeed not show too much difference (only up to js optimizer). No, the browser doesn't have to repaint, nor to do a reflow at every changes in the DOM. In best case, they will do it only once (generally just before the next screen refresh). However, [some DOM methods will force a reflow](https://gist.github.com/paulirish/5d52fb081b3570c81e3a), and if you do call one of these methods in your loop, then you'll see an huge difference. – Kaiido Sep 27 '18 at 05:26
  • @Kaiido thanks, I just spent a bit of time playing with it and that does indeed seem to be the case. I knew about how some methods will force a reflow but I thought for some reason that making any changes to the DOM would have similar side effects - why else would react use a "shadow dom" for example. I'd love for a detailed breakdown if someone wants to answer but I'm also thinking about just spending some more time researching myself and answering my own question, ha. – Rose Robertson Sep 27 '18 at 19:57

0 Answers0