[ACCEPTED]-Deep cloning vs setting of innerHTML: what's faster?-dhtml
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;) {
f();
}
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:
IE7
cloneNode: 3238, 3235, 3187
innerHTML: 8442, 8468, 8552
Firefox3
cloneNode: 1294, 1315, 1289
innerHTML: 3593, 3636, 3580
Safari3
cloneNode: 207, 273, 237
innerHTML: 805, 818, 786
Chrome1
cloneNode: 329, 377, 426
innerHTML: 2327, 2536, 2865
Opera10
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.
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
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.