深度克隆与innerHTML的设置:什么更快?

时间:2009-03-24 05:32:28

标签: javascript dom dhtml

我正在尝试找出在浏览器中深度克隆DOM树的最高效方法。

如果我从

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

什么会更快,

var target = div.cloneNode(true);

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

我理解浏览器平台可能会在这里产生很大的不同,因此任何有关如何在现实世界中进行比较的信息都会受到赞赏。

3 个答案:

答案 0 :(得分:50)

我们来试试吧!

我将以下代码添加到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.innerHTML;
//    clones.push(d);
//}))

以下是在Core 2 Q9300上的VirtualBox上运行的结果:

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子操作通常很慢的原因是你一个接一个地插入/移动它们;像cloneNode这样的一次性DOM操作不必这样做。

Safari设法快速地完成innerHTML操作,但仍然没有像cloneNode那么快。正如预期的那样,IE是一只狗。

所以,对于那些说innerHTML显然会更快而不考虑问题实际上在做什么的人来说,自动-1全面。

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

// 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使用Element.attachEvent()来实现自己的事件系统,所以自然需要避免这个bug。如果您不需要,可以避免开销。

[偏离主题:再说一遍,我认为将jQuery提升为最佳实践的顶峰可能有点误,特别是考虑到下一行:

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

没错 - jQuery将自己的任意属性添加到HTML元素中,然后在克隆它们时需要摆脱它们(或以其他方式访问它们的标记,例如通过$()。html()方法) 。这很丑陋,但后来它认为最好的方法是使用正则表达式处理HTML,这是一种基本的错误,你期望更多来自天真的1-reputation SO提问者而不是第二次来自最佳JS的作者框架Evar。

希望你的文字内容中没有任何字符串“jQuery1 =”2“”,如果是这样你就会神秘地失去它。谢谢jQuery!因此,结束了偏离主题。]

答案 1 :(得分:1)

嗯......有趣的是,我刚刚在Firefox 3中进行过测试,而深度克隆似乎比使用innerHTML路线快3倍。

我确信innerHTML仍然比单个DOM操作更快,但至少对于深度克隆,cloneNode(true)似乎更好地进行了优化。

答案 2 :(得分:-5)

一般来说,innerHTML更快。看看这个,benchmark across many platforms