选择器的性能在浏览器之间会有很大差异。例如。有querySelector
和querySelectorAll
(QSA)与没有。没有 QSA 时,有getElementsByClassName
或没有。
选择器引擎需要做的工作量会有所不同。
你可以用不同的方式写这个。3 种方法,而不仅仅是 2 种:
1.$('accountDetailsTable').getElements('.toggler')
上面的解剖是:
- 获取元素(1 次调用)。
- 从元素原型(或直接在旧 IE 中的元素)调用 getElements 方法
- 查找与类选择器匹配的所有子节点
这在浏览器中是一致的,因为它获取一个根节点并调用它的方法。如果没有 QSA,它将去getElementsByClassName
或遍历所有childNodes
并过滤className
属性,直到它有一个匹配列表。性能方面,这在现代浏览器中会更糟,因为它需要链接,而方法 3 将是直接结果。
因为选择器在 JS 中是如何工作的,与 CSS 不同——它是从左到右的,更多合格的选择器可以提高性能,这.toggler
意味着当有一个较旧的浏览器时,它不需要考虑树中的每个 DOM 节点(文本除外节点)。尽可能地限定选择器,即div.toggler
或a.toggler
.
2.$$('.toggler')
- 如果 QSA 可用,请依靠浏览器返回内容(这里没有额外的 hack,例如
:not
, or :contains
or :has
or !
(反向组合符)。
- 如果没有 QSA,它将通过 Slick 解析器解析表达式,并基本上在内部降级为类似于上述情况 1 的内容。这里最大的区别是缺少上下文——它将针对整个文档运行,因为 $$ 内部会执行类似的操作
document.getElements('.toggler')
,因此需要考虑更多节点。始终将您的查询锚定到一个稳定的最常见的节点。或将其传递到查询字符串中以进行限定,如案例 3
再一次,这将通过使其更合格来提高性能,例如:
$$('a.toggler')
3.$$('#accountDetailsTable .toggler')
- 与案例 2 类似,但当 QSA 可用时,它会更快。
- 当 QSA 不存在时,它将针对 #accountDetailsTable 节点的上下文运行,因此它会比情况 2 更好。
使这更合格将有所作为:
$$('#accountDetailsTable td.control > a.toggler')
大折扣:这取决于您的 DOM 有多大,找到并返回了多少匹配项。在简单的 DOM 上,预期的性能顺序可能会有所不同。
如今,选择器的性能优化越来越无关紧要。
SlickText 比较框架的时代已经结束,应用程序性能与选择器速度几乎没有关系,或者您做错了什么。
如果你的工作做得对,你就不需要不断地选择元素。您可以缓存东西、重用、智能并将 DOM 查找减少到最低限度。
事件等可以通过智能事件委托附加,在适当的情况下,完全不需要选择和添加事件到多个节点等 - 使用常识,不要挂在理论性能基准上。相反,请使用分析器并测试您的实际应用程序,看看您在哪里浪费时间/CPU 周期。
您可以在一秒钟内运行这样一个简单的选择器超过 50000 次。这是微基准测试,并不能衡量您的 APP、DOM、浏览器等内部的实际性能。
关于基准测试性能和过早优化的更多想法:http ://www.youtube.com/watch?v=65-RbBwZQdU
小心
首先写正确性和可读性。即使你可以通过做某事获得额外的性能,如果它不是关键/一直重用,也不要以牺牲可读性为代价。像.toggler
,.new
等选择器.button
往往过于通用,并且可以在 DOM 的不同部分的应用程序中重用。您需要限定选择器以确保您的预期功能在移动到不同的页面/小部件/DOM 并且您的项目获得新开发人员涌入时继续工作。
只是我的两分钱,我知道你已经接受了答案。