Why You Should Use Document Fragments

Why You Should Use Document Fragments

Looking at the benefits of using document fragments
Ferenc Almasi β€’ Last updated 2021 November 11 β€’ Read time 4 min read
If you make heavy use of DOM manipulations, you might be want to optimize your calls by using document fragments. Find out how they can improve performance.

There are countless options to optimize performance, starting from image and font optimization, all the way to optimizing JavaScript.

A common scenario that can take a toll on your performance, is the heavy manipulation of the DOM. React solves this with a virtual DOM, which is a JavaScript representation of the real DOM tree. But what if you are not working in React? You want things to work smoothly in vanilla JavaScript.

Document Fragments might be what you are looking for. It is a web API that is used as a lightweight alternative to Document. It works just like the regular document, but initially, it has no parent. Therefore, the key difference between a document fragment and the real DOM, is that it is not part of the real DOM. It only becomes part of it, once you add it.


How Document Fragments Work

To create a new document fragment, all you have to do is call it with the new keyword:

Copied to clipboard!
new DocumentFragment();

If you initialize it in your DevTools and store it in a global variable, you will be able to see that it has all the methods you usually find on the real DOM, yet this is detached until you actually add it.

Inspecting a document fragment in DevTools
The same properties and methods you would find on a DOM element, are available on a DocumentFragment

What is the Benefit of Using it?

The most common use case you will find is when you need to construct a DOM subtree through JavaScript. For this, you can use a document fragment to prepare your elements and attach it to the real DOM once you are done. Because you insert everything once, you will only have one reflow and a single render.

Imagine you need to construct a dynamic list with a bunch of elements. If you interact with the real DOM, you potentially trigger a render and reflow for every node added. This can be avoided using document fragments.

Document fragments in action

Let’s see an example of using them. Imagine you have the following unordered list in your DOM, and you want to populate it through JavaScript:

Copied to clipboard!
<ul id="list"></ul>

Without a document fragment, you would do it in the following way:

Copied to clipboard! Playground
const unorderedList = document.getElementById('list');
const activities = ['πŸ„', '🚴', '🀸', 'πŸƒ'];

activities.forEach(activity => {
    const listItem = document.createElement('li');
  
    listItem.innerText = activity;
    unorderedList.appendChild(listItem);
});
populate.js

You get the element from the DOM and you loop through your data. For each entry, you create a new li element and append it to the list. Although this is heavily optimized internally by browsers, you are doing more interaction with the DOM than necessary. With document fragments, you would do it in the following:

Copied to clipboard! Playground
const unorderedList = document.getElementById('list');
const activities = ['πŸ„', '🚴', '🀸', 'πŸƒ'];
const fragment = new DocumentFragment();

activities.forEach(activity => {
    const listItem = document.createElement('li');
  
    listItem.innerText = activity;
    fragment.appendChild(listItem);
});

unorderedList.appendChild(fragment);
populate.js

Again, the first two lines are the same; you get the DOM element and your data, but you also need to set up a new DocumentFragment. The loops almost look identical, but there is a big difference. As you can see, instead of appending each list element directly to the DOM, the loop attaches them to the fragment. After the loop, we attach the whole list only once to the list.

Note that when you append a fragment to the DOM, you are left with an empty fragment.

This means, you don’t need to create a new fragment, you can reuse them same, multiple times.

For complex DOM subtrees, you also have the option to use a DOMParser. This can make your code more readable, and again, you don’t interact with the real DOM for each node you make. However, note that it is not as efficient as using a document fragment.

Copied to clipboard! Playground
const domContent = `
    <ul>
        ${activities.map(activity => `<li>${activity}</li>`).join('')}
    </ul>
`;

const parser = new DOMParser().parseFromString(domContent, 'text/html');

unorderedList.replaceWith(parser.getElementsByTagName('ul')[0]);
DOMParser.js
Looking to improve your skills? Check out our interactive course to master JavaScript from start to finish.
Master JavaScriptinfo Remove ads

Conclusion

In conclusion, if you have to do heavy DOM manipulation, or you need to dynamically append items in loops, you can opt-in using document fragments to improve your performance. To see how each of the solutions perform, I’ve created a benchmark test that you can run on JSBench.me.

Benchmark results of document fragments

If you would like to learn more about performance optimization, make sure you continue your journey with the article below. Thank you for reading through, happy coding!

10 Critical Performance Optimization Steps You Should Take
Did you find this page helpful?
πŸ“š More Webtips
Frontend Course Dashboard
Master the Art of Frontend
  • check Access 100+ interactive lessons
  • check Unlimited access to hundreds of tutorials
  • check Prepare for technical interviews
Become a Pro

Courses

Recommended

This site uses cookies We use cookies to understand visitors and create a better experience for you. By clicking on "Accept", you accept its use. To find out more, please see our privacy policy.