[ACCEPTED]-Deep cloning vs setting of innerHTML: what's faster?-dhtml

Accepted answer
Score: 57

Let's test!

I added the following code to 41 a copy of StackOverflow's Questions page 40 (removing existing scripts first, and running 39 from scratch with one of the timeit()s uncommented 38 each time around, three runs of 100 ops:

function timeit(f) {
    var start= new Date();
    for (var i=100; i-->0;) {
    return new Date()-start;

var c= document.getElementById('content');
var clones= [];

//alert('cloneNode: '+timeit(function() {
//    clones.push(c.cloneNode(true));

//alert('innerHTML: '+timeit(function() {
//    var d= document.createElement('div');
//    d.innerHTML= c.innerHTML;
//    clones.push(d);

Here 37 are the results running on a VirtualBox 36 on a Core 2 Q9300:

cloneNode: 3238, 3235, 3187
innerHTML: 8442, 8468, 8552

cloneNode: 1294, 1315, 1289
innerHTML: 3593, 3636, 3580

cloneNode: 207, 273, 237
innerHTML: 805, 818, 786

cloneNode: 329, 377, 426
innerHTML: 2327, 2536, 2865

cloneNode: 801, 791, 771
innerHTML: 1852, 1732, 1672

So cloneNode(true) is much faster than 35 copying innerHTML. Of course, it was always going 34 to be; serialising a DOM to text and then 33 re-parsing it from HTML is hard work. The 32 reason DOM child operations are usually 31 slow is that you're inserting/moving them 30 one-by-one; all-at-once DOM operations like 29 cloneNode don't have to do that.

Safari manages to 28 do the innerHTML op amazingly quickly, but still 27 not nearly as quickly as it does cloneNode. IE is, as 26 expected, a dog.

So, auto -1s all round to 25 everyone who said innerHTML would Obviously 24 Be Faster without considering what the question 23 was actually doing.

And yes, jQuery uses 22 innerHTML to clone. Not because it's faster 21 though — read the source:

// IE copies events bound via attachEvent when
// using cloneNode. Calling detachEvent on the
// clone will also remove the events from the orignal
// In order to get around this, we use innerHTML.

jQuery uses Element.attachEvent() to 20 implement its own event system, so naturally, it 19 needs to avoid that bug. If you don't need 18 to, you can avoid the overhead.

Off-topic aside: Then again, I 17 think holding jQuery up as the pinnacle 16 of Best Practice may be a bit mistaken, especially 15 given the next line:

html.replace(/ jQuery\d+="(?:\d+|null)"/g, "")

That's right — jQuery 14 adds its own arbitrary attributes to HTML 13 elements and then needs to get rid of them 12 when it clones them (or otherwise gives 11 access to their markup, such as through 10 the $().html() method). This is ugly enough, but then 9 it thinks the best way to do that is processing 8 HTML using a regular expression, which is 7 the kind of basic mistake you'd expect more 6 from naïve 1-reputation SO questioners than 5 the author of the Second Coming Best JS 4 Framework Evar.

Hope you didn't have the 3 string jQuery1="2" anywhere in your text content, 'cos 2 if so you just mysteriously lost it. Thanks, jQuery! Thus 1 ends the off-topic aside.

Score: 1

Hmmm... interestingly, I just did a test 6 in Firefox 3, and a deep clone seems to 5 be about 3 times faster than going the innerHTML 4 route.

I'm sure innerHTML is still faster 3 than individual DOM operations, but at least 2 for deep cloning, cloneNode(true) seems 1 to be better optimized.

More Related questions