javascript - 深度克隆与 innerHTML : what's faster? 的设置

标签 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;

我知道浏览器平台在这里可能会有很大的不同,所以任何关于这些在现实世界中如何比较的信息都将不胜感激。

最佳答案

让我们测试一下!

我将以下代码添加到 StackOverflow 问题页面的副本(首先删除现有脚本,然后从头开始运行其中一个 timeit() 每次都取消注释,运行 3 次 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() 来实现自己的事件系统,因此自然需要避免该错误。如果不需要,可以避免开销。

题外话:话又说回来,我认为将 jQuery 视为最佳实践的顶峰可能有点错误,尤其是考虑到下一行:

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

没错⟩—⟩jQuery 将自己的任意属性添加到 HTML 元素,然后在克隆它们时需要摆脱它们(或者以其他方式提供对其标记的访问,例如通过 $().html() 方法)。这已经够丑陋了,但它认为最好的方法是使用正则表达式处理 HTML,这是一种基本错误,你会从天真的 1-reputation SO 提问者那里得到更多,而不是 Second Coming Best 的作者JS 框架变量。

希望您的文本内容中没有字符串 jQuery1="2" ,因为如果是这样,您只是神秘地丢失了它。谢谢,jQuery!题外话到此结束。

关于javascript - 深度克隆与 innerHTML : what's faster? 的设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/676249/

相关文章:

javascript - 在 DHTML 中用 ActionScript 替换 JavaScript

javascript - 带有 setTimeout 的 Jquery 效果

dhtml - 菜单dhtml和css的问题

java - GWT 交换机性能 - PMD 的建议

javascript - 如何防止方法的 `this` 引用到调用它的对象

javascript - 什么会导致 setTimeout(callback, 0) 的回调延迟

javascript - 如何关闭 iframe?

javascript - Node.normalize() 在 IE6 中崩溃

javascript - 向后查找替换所有出现的情况

javascript - 检测输入字段是否生成了自动建议列表?