Skip to content

Instantly share code, notes, and snippets.

@fearphage
Created September 20, 2012 14:45
Show Gist options
  • Save fearphage/3756350 to your computer and use it in GitHub Desktop.
Save fearphage/3756350 to your computer and use it in GitHub Desktop.
Can you make this faster?

The goal is to add N new elements to the DOM as quickly and as painlessly as possible.

I have access to jQuery and found the code below to be faster than the following:

$(parentElement)
  .append(Array(1001).join(template))
;
var
fragment = document.createDocumentFragment()
,div = document.createElement('div')
,temp = '<div class="foo"><a href=#">bar</a><span class="catpants">baz</span></div>'
;
div.innerHTML = Array(1001).join(temp);
while (temp = div.firstChild) {
fragment.appendChild(temp);
}
parentElement.appendChild(fragment);
@WebReflection
Copy link

if parentElement is empty, !parentElement.firstChild, you can skip the loop and use innerHTML directly so that
parentElement.innerHTML = Array(1001).join(temp);
So, basically, you miss an if that checks if nothing is there, inject directly ... otherwise the technique seems to be a good one, imho

@WebReflection
Copy link

also ... if nodes inside parentElement are less than node to insert ... maybe it makes sense to hold them, use innerHTML, and place them again through fragment

var tmp, fragment = document.createDocumentFragment();
while (tmp = parentElement.firstChild) fragment.appendChild(tmp);
parentElement.innerHTML = Array(1001).join(template);
parentElement.insertBefore(fragment, parentElement.firstChild);

latter idea/hint requires a bench in any case ;)

@fearphage
Copy link
Author

I'm appending to the parentElement. I can''t innerHTML it without +=. The 1000 number is arbitrary and on the high end of normal use. In most cases, there will be 50 elements before the placeholder elements. I'll look into the 2nd solution. I like the idea.

@dperini
Copy link

dperini commented Sep 20, 2012

Yes fragments + cloneNode() is always faster than innerHTML, at least that's what I tested long ago.

Take this as a start:

window.onload = function() {
    var i = 0, start, end, tmp, fragment = document.createDocumentFragment(),
        temp = '<div class="foo"><a href=#">bar</a><span class="catpants">baz</span></div>',
        div = document.createElement('div'),
        parentElement = document.body;

    start = new Date().getTime();
    div.innerHTML = temp;
    tmp = div.firstChild;
    while (1000 > i++) fragment.appendChild(temp.cloneNode(true));
    parentElement.appendChild(fragment);
    end = new Date().getTime();
    console.log(end - start);
}

tested on Chrome/Opera to be almost 2x faster, and on Firefox/Safari still faster but not that much.

@dperini
Copy link

dperini commented Sep 20, 2012

A typo in the previous snippet, should be:

while (1000 > i++) fragment.appendChild(tmp.cloneNode(true));

@mathiasbynens
Copy link

You might wanna take the performance testing to jsPerf, guys ;)

@fearphage
Copy link
Author

Very nice gentlemen. I have a few ideas to test now. Thanks a lot.

@dperini
Copy link

dperini commented Sep 20, 2012

Here is my jsPerf test:

http://jsperf.com/dom-fragments-and-clonenode-vs-fragments-and-innerhtml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment