3

Is there a difference between using a document fragment or an un-appended created div to avoid multiple hits to the DOM?

Let's say we're going to generate 100 list items...

Our page's contents:

 <ul class="list"></ul>

Scenario 1: document fragment

In this scenario, we're creating the li, populating it with some simple text, then appending it to the fragment. Once the loop is finished, the fragment gets appended to the list. We avoid pinging the DOM 100x's and only ping it once to append the fragment.

var frag = document.createDocumentFragment();
for(var i = 1; i <= 100; i++) {
  var li = document.createElement('li');
  li.textContent = 'Item #' + i;
  frag.append(li);
}

document.querySelector('.list').appendChild(frag);

Scenario 2: un-appended div

In this scenario, we create a div that acts like the document fragment since it's not in the DOM. We append all the created li's to the div, then finally append the div's contents to the list in the DOM.

var div = document.createElement('div');
for(var i = 1; i <= 100; i++) {
  var li = document.createElement('li');
  li.textContent = 'Item #' + i;
  div.append(li);
}

document.querySelector('.list').innerHTML = div.innerHTML;

What's the difference between these two scenario's? As far as avoiding pinging the DOM multiple times, it seems that both achieve the same result.

The Qodesmith
  • 3,205
  • 4
  • 32
  • 45
  • If you are wondering about performance, why not create a JSPerf, like [this answer](http://stackoverflow.com/a/35242602/99777) did? – joeytwiddle Apr 10 '16 at 12:48

1 Answers1

1

The second example doesn't work.
The function appendChild must accept an object but div.innerHTML return a string.

What you can do is this:

document.querySelector('.list').appendChild(div);

But that would also insert the div. This is why the fragment exists, to be able to insert multiple elements at once without a wrapper element that could break your html structure.

You could also do this:

document.querySelector('.list').innerHTML = div.innerHTML;

But then the varibale li doesn't reference the li element in the DOM anymore. The elements in the DOM are new ones created from the div.innerHTML string.

For example if you added some event listeners to the elements they wouldn't work any more.

Andrija Čehko
  • 443
  • 8
  • 14
  • Thanks for the heads up. I've edited my code to reflect the 2nd scenario working now. Still, I'm curious as to the difference of the 2 scenarios. As far as even listeners on the li's are concerned, you could either attach them after scenario 2 has run, or, before hand with event delegation and the listener on the body. – The Qodesmith Apr 10 '16 at 12:28
  • 1
    I think it's more of a personal preference. You can use what you like. With the second scenario you can easily overwrite the contents of the `.list` element. While with the first one you just add more elements to it. You can also use `innerHTML += div.innerHTML` to add instead of replace. But if there are any events directly on the elements, without delegation they would stop working. – Andrija Čehko Apr 10 '16 at 12:53