I recently found out about DocumentFragment
, which is something I had never heard of before so I figured maybe a lot of other people never came across it either.
A DocumentFragment
is described on MDN as
a lightweight version of Document that stores a segment of a document structure comprised of nodes just like a standard document. The key difference is due to the fact that the document fragment isn't part of the active document tree structure. Changes made to the fragment don't affect the document (even on reflow) or incur any performance impact when changes are made.
Each time you add elements to the DOM, the page has to immediately update. For example, say you have a lot of items you want to add to a list. Below is a silly example that loops 10,000 times and each time it creates an <li>
element, appends that to a <ul>
that exists in the DOM already, and for each of those iterations there is an inner loop that runs 100 times. Each of those times it creates a <p>
element, appends it to the previously created <li>
, and creates a text node with the current count
value, which is then appended to the <p>
. Every time it appends an element the DOM has to update. This code would result in A LOT of updates.
const ul = document.querySelector('ul');
let count = 0, li, p;
for (let i = 0; i < 10000; i++) {
li = document.createElement('li');
ul.appendChild(li);
while (count < 100) {
p = document.createElement('p');
li.appendChild(p);
p.appendChild(document.createTextNode(count));
count++;
}
count = 0;
}
Because fragments aren't part of the DOM, the contents that are added to it won't be rendered until the fragment is appended to the document. By using a fragment, you can append as many elements as you want to it as you're looping and then add the fragment into the document after. In this example, once the fragment is added its child nodes are removed and placed onto the <ul>
. The fragment itself is not added into the document.
const ul = document.querySelector('ul');
let count = 0, li, p;
const fragment = document.createDocumentFragment();
for (let i = 0; i < 10000; i++) {
li = document.createElement('li');
fragment.appendChild(li);
while (count < 100) {
p = document.createElement('p');
li.appendChild(p);
p.appendChild(document.createTextNode(count));
count++;
}
count = 0;
}
ul.appendChild(fragment);
Using DocumentFragment
helps when manipulating the DOM to avoid unnecessary re-renders, which results in faster code.
Top comments (1)
That's a great question and I'm not really sure. From what I can tell, if you're only appending a few things it doesn't seem like it makes that much of a difference, but hopefully someone with more experience can weigh in.