Should I use document.createDocumentFragment or document.createElement

JavascriptDom

Javascript Problem Overview


I was reading about document fragments and DOM reflow and wondered how document.createDocumentFragment differed from document.createElement as it looks like neither of them exist in the DOM until I append them to a DOM element.

I did a test (below) and all of them took exactly the same amount of time (about 95ms). At a guess this could possibly be due to there being no style applied to any of the elements, so no reflow maybe.

Anyway, based on the example below, why should I use createDocumentFragment instead of createElement when inserting into the DOM and whats the differnce between the two.

var htmz = "<ul>";
for (var i = 0; i < 2001; i++) {
    htmz += '<li><a href="#">link ' + i + '</a></li>';
}
htmz += '<ul>';

//createDocumentFragment
console.time('first');
var div = document.createElement("div");
div.innerHTML = htmz;
var fragment = document.createDocumentFragment();
while (div.firstChild) {
    fragment.appendChild(div.firstChild);
}
$('#first').append(fragment);
console.timeEnd('first');

//createElement
console.time('second');
var span = document.createElement("span");
span.innerHTML = htmz;
$('#second').append(span);
console.timeEnd('second');


//jQuery
console.time('third');
$('#third').append(htmz);
console.timeEnd('third');

Javascript Solutions


Solution 1 - Javascript

The difference is that a document fragment effectively disappears when you add it to the DOM. What happens is that all the child nodes of the document fragment are inserted at the location in the DOM where you insert the document fragment and the document fragment itself is not inserted. The fragment itself continues to exist but now has no children.

This allows you to insert multiple nodes into the DOM at the same time:

var frag = document.createDocumentFragment();
var textNode = frag.appendChild(document.createTextNode("Some text"));
var br = frag.appendChild(document.createElement("br"));
var body = document.body;
body.appendChild(frag);
alert(body.lastChild.tagName); // "BR"
alert(body.lastChild.previousSibling.data); // "Some text"
alert(frag.hasChildNodes()); // false

Solution 2 - Javascript

Another very important difference between creating an element and a document fragment:

When you create an element and append it to the DOM, the element is appended to the DOM, as well as the children.

With a document fragment, only the children are appended.

Take the case of:

var ul = document.getElementById("ul_test");


// First. add a document fragment:


(function() {
  var frag = document.createDocumentFragment();
  
  
  var li = document.createElement("li");
  li.appendChild(document.createTextNode("Document Fragment"));
  frag.appendChild(li);
  
  ul.appendChild(frag);
  console.log(2);
}());

(function() {
  var div = document.createElement("div");
  
  
  var li = document.createElement("li");
  li.appendChild(document.createTextNode("Inside Div"));
   div.appendChild(li);
  
  ul.appendChild(div);
}());

Sample List:
<ul id="ul_test"></ul>

which results in this malformed HTML (whitespace added)

<ul id="ul_test">
  <li>Document Fragment</li>
  <div><li>Inside Div</li></div>
</ul>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionscreenm0nkeyView Question on Stackoverflow
Solution 1 - JavascriptTim DownView Answer on Stackoverflow
Solution 2 - JavascriptJeremy J StarcherView Answer on Stackoverflow