维护活动的HTMLCollection的性能成本是多少?

5

我的前端JS代码的一部分依赖于一个包含数千个DOM节点的实时HTMLCollection。由于它是实时的,因此随着DOM的更新而自动更新。

这是否与每次修改DOM时重新运行document.getElementsByClassName调用相同,还是在幕后进行了性能优化?


这要看情况。墨菲说,如果你真的需要优化,那么在部署环境中可能不可用。如果你不需要它,那么它将可用。 - 6502
https://humanwhocodes.com/blog/2010/09/28/why-is-getelementsbytagname-faster-that-queryselectorall/ - skyboyer
1
@skyboyer 那篇文章有点误导人。创建一个实时的NodeList非常快,因为查找DOM元素的开销被推迟到访问元素时才进行。 - Barmar
@Barmar的文章指出了同样的观点:“活动NodeList对象可以更快地被浏览器创建和返回,因为它们不需要一开始就拥有所有信息,而静态NodeList需要从一开始就拥有它们的所有数据。” - skyboyer
1
@skyboyer 对的,它们可以更快地创建,但第一次访问将会慢相同的量。没有免费的午餐。 - Barmar
1个回答

5

这篇博客文章解释了静态和动态NodeLists之间的一些差异,并提到了动态集合的实现方式。

动态集合直到访问其元素时才会访问DOM。此时,它会创建实际的集合并缓存它。如果DOM不发生变化,则未来访问没有任何开销。

更改DOM不应立即更新任何集合。相反,它应该只是使它们的缓存无效。下次访问其中一个集合时,它将被重新生成。

因此,如果您创建了动态集合并相对于DOM修改很少访问它,则开销应该相对较小。最糟糕的情况是,如果您在循环过程中遍历动态集合并修改DOM,则每次迭代都必须更新集合。

可能有其他优化措施可以减轻这种情况。对于某些类型的实时集合,JavaScript 引擎可以判断特定的 DOM 修改是否会影响它;如果不会,则不必使集合无效。例如,使用 document.getElementsByClassName() 创建的集合不会受到未在任何地方添加或删除指定类的修改的影响。但是,如果您执行像删除元素这样的操作,则必须检查该元素为根的子树中是否出现了该类,因此这并不比使缓存无效更好。


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