Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is appending to an element not yet in the DOM faster than using a javascript Fragment?

Tags:

javascript

Consider these three versions of appending lis to a ul:

Naive Version (20% slower):

var ul = document.getElementById('targetUl');

for (var i = 0; i < 200; i++) {
  var li = document.createElement('li');
  li.innerHTML = Math.random();
  ul.appendChild(li);
}

Using a JavaScript Fragment (4% slower):

var ul = document.getElementById('targetUl'),
    fragment = document.createDocumentFragment();

for (var i = 0; i < 200; i++) {
  var li = document.createElement('li');
  li.innerHTML = Math.random();
  fragment.appendChild(li);
}
ul.appendChild(fragment);

Appending to an element not yet in the DOM (1.26% faster):

var ul = document.createElement('ul'),
    div = document.getElementById('targetDiv');

for (var i = 0; i < 200; i++) {
  var li = document.createElement('li');
  li.innerHTML = Math.random();
  ul.appendChild(li);
}
div.appendChild(ul);

Why is appending to a DOM element held in memory faster than appending to a Fragment? Since fragment was created for this sole purpose shouldn't it be faster? Are they're any advantages to using a fragment over an element held in memory other than not having to include a top level element before appending?

Check the test output from jsperf: http://jsperf.com/javascript-fragments-tests

like image 741
agconti Avatar asked Jul 22 '14 03:07

agconti


1 Answers

It is a bit more work to insert multiple children from a document fragment (particularly when your test has 200 children) than it is to insert a single parent <ul> tag.

So, with the fragment, you're reparenting 200 <li> elements from the fragment to your <ul> tag in the DOM.

With your last code block, you're just reparenting the one <ul> tag by inserting it into the DOM.

So, in your particular example, using the document fragment creates more work for the insertion into the DOM than the way you run your last example that just has to insert the single <ul> tag.


The fragment has its tactical advantages when you want to keep track of a whole bunch of elements at the same level and then insert them with one line of code and you the parent is already in the DOM. But, it isn't always the fastest way to do things vs. a scenario where you can collect all the items out of the DOM at the same level under their actual parent node and then insert just that parent node.

like image 164
jfriend00 Avatar answered Oct 27 '22 03:10

jfriend00