深层克隆与innerHTML的设置:更快? [英] Deep cloning vs setting of innerHTML: what's faster?

查看:122
本文介绍了深层克隆与innerHTML的设置:更快?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



如果我开始使用

$,那么我试图找出在浏览器中深入克隆一个DOM树的最好的方法。 b
$ b

  var div = document.getElementById(source); 
var markup = div.innerHTML;

什么会更快,

  var target = div.cloneNode(true); 

  var target = document.cloneNode(false); 
target.innerHTML = markup;

我明白浏览器平台可能在这里有很大的区别,所以有关这些比较的信息

解决方案

我们来试试吧



将以下代码添加到StackOverflow的问题页面的副本中(首先删除现有脚本,并从头开始运行,其中一个timeit()每次不注释,三次运行100次操作:

  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.innerHTM L;
// clones.push(d);
//}))

这是运行在Core 2上的VirtualBox上的结果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

因此,cloneNode(true)比复制innerHTML要快得多。当然会是这样的事情将DOM连接到文本,然后从HTML重新解析它是很难的。 DOM子操作通常较慢的原因是您正在逐个插入/移动它们;一次性的DOM操作,如cloneNode不需要这样做。



Safari设法做到innerHTML的操作非常快,但仍然不会像做cloneNode。 IE正如预期的那样,一只狗。



所以,对于所有内在的HTML来说,自动-1都会显而易见,而不考虑问题的实际情况。 / p>

是的,jQuery使用innerHTML进行克隆。不是因为它的速度更快 - 阅读来源:

  // IE复制通过attachEvent绑定的事件
//使用cloneNode。调用
// clone上的detachEvent也会从orignal
//中删除事件//为了解决这个问题,我们使用innerHTML。

jQuery使用Element.attachEvent()来实现自己的事件系统,所以自然需要避免错误。如果你不需要,你可以避免开销。



[脱离主题:再次,我认为把jQuery作为最佳实践的顶峰可能有点错误,特别是下一行:

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

没错 - jQuery添加自己的任意属性到HTML元素,然后在克隆它们时需要摆脱它们(或者以其他方式访问它们的标记,例如通过$()。html()方法)。这很丑陋,但是认为最好的方式是使用正则表达式来处理HTML,这是您从预期更多来自初始1声誉SO提问者的基本错误,而不是Second Coming Best JS的作者框架Evar。



希望你没有字符串jQuery1 =2你的文本内容的任何地方,'cos如果你只是神秘地失去了它。谢谢jQuery!因此结束了脱离主题。]


I'm trying to figure out the most performant way of deep-cloning a DOM tree within the browser.

If I start out with

var div = document.getElementById("source");
var markup = div.innerHTML;

What will be faster,

var target = div.cloneNode(true);

or

var target = document.cloneNode(false);
target.innerHTML = markup;

I understand the browser platform may make a big difference here, so any information about how these compare in the real world would be appreciated.

解决方案

Let's test!

I added the following code to a copy of StackOverflow's Questions page (removing existing scripts first, and running from scratch with one of the timeit()s uncommented 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 are the results running on a VirtualBox 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 copying innerHTML. Of course it was always going to be; serialising a DOM to text and then re-parsing it from HTML is hard work. The reason DOM child operations are usually slow is that you're inserting/moving them one-by-one; all-at-once DOM operations like cloneNode don't have to do that.

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

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

And yes, jQuery uses innerHTML to clone. Not because it's faster 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 implement its own event system, so naturally it needs to avoid that bug. If you don't need to, you can avoid the overhead.

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

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

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

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

这篇关于深层克隆与innerHTML的设置:更快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆