how Document Fragment works?

Jeffrin John picture Jeffrin John · Aug 7, 2017 · Viewed 7.1k times · Source

Can anyone please explain briefly what documentFragment actually does. I have been searching for a clear explanation but I don't get any until now.

what I read is, documentFragment is something like DOM like structure where we can add modify DOM element without interrupting the actual flow of the document.

I also read, documentFragment is faster than appending each element into DOM one by one. It felt to me like, documentFragment does not recalculate styles every time so it is faster.

I have two examples,

DOING IT IN FRAGMENT WAY:

var frag = document.createDocumentFragment();
var div1 = document.createElement("div");
var div2 = document.createElement("div");
frag.appendChild(div1);
frag.appendChild(div2);
document.getElementById("someId").appendChild(frag);

DOING IT IN NORMAL WAY:

var div = document.createElement("div");
var div1 = document.createElement("div");
var div2 = document.createElement("div");
div.appendChild(div1);
div.appendChild(div2);

document.getElementById("someId").appendChild(div);

what actually happens in above two examples?

Answer

PeterMader picture PeterMader · Aug 7, 2017

There's an important difference between "the fragment way" and "the normal way":

Using document.createElement:

const div = document.createElement('div');
div.appendChild(document.createTextNode('Hello'));
div.appendChild(document.createElement('span'));
document.body.appendChild(div);
console.log(div.childNodes); // logs a NodeList [#text 'Hello', <span>]

This results in the following DOM structure:

<body>
  <div>
    Hello
    <span></span>
  </div>
</body>

Using DocumentFragment:

const frag = document.createDocumentFragment();
frag.appendChild(document.createTextNode('Hello'));
frag.appendChild(document.createElement('span'));
document.body.appendChild(frag);
console.log(frag.childNodes); // logs an empty NodeList

This results in the following DOM structure:

<body>
  Hello
  <span></span>
</body>

That means that calling appendChild or insertBefore with an instance of DocumentFragment moves the child nodes of the document fragment to the new parent node. After that, the document fragment is empty.

As you have correctly mentioned, it can be more efficient to create a document fragment and append multiple elements to it than to append those elements to the real DOM one by one, causing the browser to re–render parts of the page every time. Because the contents of the document fragment are not visible on screen, the page has to be re–rendered only once.

Whenever you create a large DOM structure, it can be advisable to create it within a document fragment and append that to the DOM when you're done.