Last Updated: January 18, 2018
· thomaslindstr_m

Why you should always append DOM elements using DocumentFragments

If you ever find yourself appending a series of elements to the DOM, you should always use a DocumentFragment to do just that.

A DocumentFragment is a minimal document object that has no parent. It is used as a light-weight version of document to store well-formed or potentially non-well-formed fragments of XML.

Why? Not only is using DocumentFragments to append about 2700 times faster than appending with innerHTML, but it also keeps the recalculation, painting and layout to a minimum.

TL;DR: Use DocumentFragments. http://jsperf.com/document-fragment-vs-innerhtml-vs-looped-appendchild

When normally we would do this to append elements:

var i = 0; while (i < 200) {
    div.innerHTML += '<li>My list item #' + i + '</li>';
i++; }

doing this would be much faster (although not optimal):

var i = 0; while (i < 200) {
    var el = document.createElement('li');
    el.innerText = 'This is my list item number ' + i;
i++; }

However, this solution suffers from recalculation of styles, painting and layout - a lot of it - something you should be very wary about when building performant web apps.

Read more about recalculation of styles, painting and layout here: http://stackoverflow.com/questions/11623299/what-does-recalculate-layout-paint-mean-in-chrome-developer-tool-timeline-record

Wouldn't it be great if there was some way to bypass recalculating, painting and layout for every single element we added, and rather have it just happen once? There is!

var el;
var i = 0;
var fragment = document.createDocumentFragment();

while (i < 200) {
    el = document.createElement('li');
    el.innerText = 'This is my list item number ' + i;
i++; }


Instead of appending the elements directly to the document when they are created, append them to the DocumentFragment instead, and finish by adding that to the DOM.

Now there's only one (big) DOM change happening, and because of that we're also keeping the recalculation, painting and layout to an absolute minimum.

Say Thanks

9 Responses
Add your response


Did not know this, will check it out. Thx!

over 1 year ago ·

great post, its funny how a lot of "developers" do just that they append elements while inside a loop not concerning themselves with repaints or reflows... thanks for posting!

over 1 year ago ·

Thanks guys! I think reflows and repaints should be lifted "out of the hood," because right now, even in modern developer tools, it's hard to actually understand what causes them and how to track them down.

over 1 year ago ·
Zp0ano7y normal

Thanks man! It helped me improving my code!

over 1 year ago ·

You may also want to move the 'el' declaration outside the loop and just set it with in the loop. It should also increase performance.

over 1 year ago ·

According to the following, using the "innerText" property does not seem like a good idea (unless things have changed a lot in the past 3 years):

over 1 year ago ·

But what if I need to append multiple fragments into multiple divs? I mean not only single one as it was in example div.appendChild(fragment);
but something like:

12 months ago ·

I tried to build a jsperf to verify this claim, but I failed.
Maybe it is a recent optimization?
I see no reason for a browser to have to immediately trigger reflow/redraws anyways.

2 months ago ·

Interestingly, it seems browsers these days have optimized, so that multiple writes to the DOM in the same synchronous code don't cause reflow, then finally the next frame will reflow and paint. In the perf test you linked, the appending version is the fastest for me in Chrome. It probably used to be slower than the DocumentFragment version, and the DocumentFragment version probably hasn't gotten slower, but the appendChild method is now faster! This is why some people suggest to batch reads and write and not mix them, otherwise a read can trigger a reflow, so interleaving them together causes many reflows.

28 days ago ·