The DocumentFragment is a lightweight, “minimal” document object that acts as a temporary container for DOM nodes. It is often referred to as a virtual DOM node because it exists entirely in memory and is not part of the active document tree. Its primary purpose is to group multiple elements together so they can be added to the live DOM in a single operation, drastically improving web performance.
1. Syntax and Creation
You create a fragment using the document factory method. It starts as an empty, transparent container.
const fragment = document.createDocumentFragment();
2. The Performance Problem: Reflows
Every time you append an element directly to the live DOM (e.g., document.body.appendChild(el)), the browser must calculate the geometry and position of elements on the page. This process is called a Reflow. If you append 1,000 items in a loop, you trigger 1,000 reflows, which can cause visible stuttering and high CPU usage.
The Inefficient Way:
const list = document.getElementById('myList');
for (let i = 0; i < 1000; i++) {
const li = document.createElement('li');
li.textContent = `Item ${i}`;
list.appendChild(li); // ❌ 1,000 separate reflows triggered here
}
3. The Efficient Way: Batching with DocumentFragment
When you append elements to a DocumentFragment, no layout calculations occur because the fragment is invisible to the browser’s rendering engine. Once the fragment is fully populated, you append it to the live DOM once.
const list = document.getElementById('myList');
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const li = document.createElement('li');
li.textContent = `Item ${i}`;
fragment.appendChild(li); // ✅ Zero reflows (happening in memory)
}
list.appendChild(fragment); // ✅ Exactly 1 reflow for all 1,000 item
4. Unique Characteristics of DocumentFragment
The “Disappearing” Act
A DocumentFragment is not a parent in the traditional sense. Once you append it to the DOM, the fragment stays in your variable, but it becomes empty. The children are literally moved, not cloned.
const frag = document.createDocumentFragment();
const p = document.createElement('p');
frag.appendChild(p);
console.log(frag.childNodes.length); // 1
document.body.appendChild(frag);
console.log(frag.childNodes.length); // 0 (It's now empty!)
5. Advanced Usage: Template Cloning
DocumentFragment is the engine behind the HTML5 <template> tag. When you access the .content property of a template, it returns a DocumentFragment. This allows you to define a structure in HTML and clone it multiple times efficiently.
// HTML: <template id="row-template"><tr><td></td></tr></template>
const template = document.querySelector('#row-template');
const tbody = document.querySelector('tbody');
const fragment = document.createDocumentFragment();
data.forEach(item => {
// .content is a DocumentFragment
const clone = template.content.cloneNode(true);
clone.querySelector('td').textContent = item.name;
fragment.appendChild(clone);
});
tbody.appendChild(fragment);
