让我们测试一下!
我将以下代码添加到 StackOverflow 问题页面的副本中(首先删除现有脚本,然后从头开始运行,timeit()
每次都未注释其中一个 s,三个运行 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 子操作通常很慢的原因是您要一个接一个地插入/移动它们;像这样的一次性 DOM 操作cloneNode
不必这样做。
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 框架 Evar。
jQuery1="2"
希望您的文本内容中没有任何字符串,因为如果是这样,您只是神秘地丢失了它。谢谢,jQuery!这样就结束了题外话。