insertAdjacentHTML为什么比innerHTML更快?

7
大约一个月前,Firefox 8实现了insertAdjacentHTML方法,这个方法是与innerHTML一起添加到IE4的。根据基准测试,insertAdjacentHTML通常比innerHTML快一个数量级
我认为两者都调用了相同的HTML解析器,那么为什么差别如此之大?insertAdjacentHTML只是一个简单的方法调用,而innerHTML是一个getter/setter,因此可能会有一些额外的开销,但我从未想象过会有这么大的差异。

请注意,使用 appendChild 要比其他两种方法快得多。这可能是因为没有必要使用解析器。相比于 appendChildinsertAdjacentHTMLinnerHTML 的区别似乎不那么重要。但是,如果你确实需要解析 HTML 字符串,appendChild 并不能提供太大帮助。此处有一个详细的 JSperf:http://jsperf.com/insertadjacenthtml-perf/28 - oriadam
2个回答

11

work.innerHTML += "<span>test</span>"相当于work.innerHTML = work.innerHTML + "<span>test</span>",也就是每次运行它都必须序列化work的所有现有内容,然后重新解析整个内容,再加上额外的

work.insertAdjacentHTML("BeforeEnd", "<span>test</span>")每次只解析一个元素,然后将这个小的文档片段附加到DOM中。


我希望一个好的浏览器能够优化 work.innerHTML += "<span>test</span>",就像现代浏览器优化字符串拼接一样,只需简单地追加到 innerHTML。虽然我可能错了,但如果没有任何浏览器供应商考虑过这个问题,那就令人惊讶了。 - Peter C
3
这并不像那么简单。序列化/解析循环具有许多副作用,例如重置某些节点属性和删除动态附加的事件处理程序。优化需要完全复制它们。浏览器制造商有更好的事情要做。Element.innerHTML += ...是一种易于在JS代码中避免的反模式。只需不要这样做即可。 - Alohci
+1 有道理。我不同意 e.innerHTML += ... 是一种反模式。在涉及 Ajax 的一些有效用途中,我不明白为什么它会有害(除了速度慢)其他地方。 - Peter C
2
@alpha123,“涉及Ajax的一些有效用途”是什么意思? - user4155172
2
现在广泛使用e.innerHTML+=...。在90%的情况下,它可以被insertAdjacentHTML替换,但由于某种原因,大多数JS程序员从未听说过它。这是一个教育问题... - oriadam

1

innerHTML 的设置器在添加新节点之前必须删除所有现有的子节点。

不知道这是唯一的原因,但肯定是一个因素。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接