The speed of jQuery.append(…)

by Warlock on Jun.22, 2010, under Javascript

I’ve been doing some JavaScript performance optimization recently and I thought I’d share some of my findings regarding jQuery.

The project I’m working involves creating large DOM trees of elements from data, and I’ve been trying to speed things up. Initially I was using jQuery.append(...) combined with document.createElement(...) in something along these lines:

var foo = $(document.createElement("span")).attr("bar", "baz");
$(parent).append(foo);

The reason for this style is because I want to be able to keep around references to the created object so I can use it later and not be forced to use selectors.

While doing some profiling, I became concerned that the append call was taking too much time, so I did some testing. Some articles I’ve read indicated that it was better to do string concatenation to create a massive strings of the elements that you wanted to create and the use a single jQuery.append(...) call to create the elements at the end. I tested that scenario as well.

My test code:

(function() {
	var start = new Date();
	var root = document.createElement("span");
	for(var i = 0; i < 100000; i++) {
		root.appendChild(document.createElement("span"));
	}
	var end = new Date();
	alert("Raw appendChild: " + (end.valueOf() - start.valueOf()));
})();

(function() {
	var start = new Date();
	var root = $(document.createElement("span"));
	for(var i = 0; i < 100000; i++) {
		root.append(document.createElement("span"));
	}
	var end = new Date();
	alert("jQuery append: " + (end.valueOf() - start.valueOf()));
})();

(function() {
	var start = new Date();
	var root = $(document.createElement("span"));
	var inners = "";
	for(var i = 0; i < 100000; i++) {
		inners += "";
	}
	root.append(inners);
	var end = new Date();
	alert("jQuery from string: " + (end.valueOf() - start.valueOf()));
})();

(function() {
    var start = new Date();
    var root = document.createElement("span");
    var inners = "";
    for(var i = 0; i < 100000; i++) {
        inners += "";
    }
    root.innerHTML = inners;
    var end = new Date();
    alert("innerHTML: " + (end.valueOf() - start.valueOf()));
})();

Run Code

The numbers I get are as follows on my Mac in Firefox are as follows (creating 10k span elements).

Raw appendChild: 304 ms
jQuery append: 5492 ms
Concatenated string (jQuery Append): 6040 ms
Concatenated string (raw innerHTML): 208 ms

My results were somewhat inconsistent. Initially when I was running this test I did see jQuery append with the concatenated string to be faster, but when running tests later, it was a bit slower. In general, I think the conclusion of the article is correct. String concatination is better than many calls to jQuery.append(...), but it doesn’t hold a candle to just doing the raw DOM manipulations. This makes sense since jQuery still has to parse the string you give it (it doesn’t feed it raw into the innerHTML) and then call the raw DOM methods directly. Lesson learned.

:,

4 Comments for this entry

  • Kartik Sehgal

    Thanks for sharing your research.

    I have added one more option which is a little faster than string concatenation (by about 10%) and the difference becomes more apparent in slower browsers like IE.

    var start = new Date();
    var arrinners = [];
    for(var i = 0; i < 10000; i++) {
    arrinners.push("”);
    }
    $(”#divcntnr”).append(arrinners.join(”));
    var end = new Date();
    alert(”jQuery from array: ” + (end.valueOf() – start.valueOf()));

  • Dusty

    Out of curiosity, what was the StdDev of your numbers (or did you just do a single run)? I did a few tries, and the raw appendChild was ranging between 300 and 500ms.

    My rough averages in Chrome 5.0.375.86 (Win32 on x64 hardware) are:

    330
    4400
    3100
    350

  • Warlock

    I only did (a highly unscientific) one run. Originally when I posted this I only had the first three methods, then I added the fourth (innerHTML) and reran all the numbers on my work computer (Firefox, 32bit Windows XP). I also ran them on Chrome, but I didn’t record what the results were.

    The gist that I took from the results was not to use jQuery.append(…) for large numbers of elements. innerHTML vs. appendChild wasn’t really a question for me because I need to be able to reference the node specifically in the future, hence I can’t just build everything into one big string.

    Thanks for running the numbers again and posting results.

  • Dusty

    Yeah, I got that the main thing was jquery.append() is an order of magnitude out, but I thought it was interesting that I was averaging only a 10x speed decrease between the last two while you were seeing 30x.

    Shame I don’t have FF on that same machine, it’d be interesting to see if it was just a FF/Chrome difference or if the arch plays a part as well.

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...