Mootools Selectors $ 或 $$.哪个性能更高
Mootools Selectors $ or $$. Which is more performant
我很好奇浏览器查找哪个选择器会更快。我对一般浏览器而不是特定浏览器感兴趣。
$('accountDetailsTable').getElements('.toggler')
这将查找accountDetailsTable
,就像您使用document.getElementById('accountDetailsTable');
一样,然后在元素内部查找.toggler
。
$$('.toggler')
而这个将直接返回所有选择器。但最终他们都会给我相同的结果。
那么哪一个会更快呢?我该如何测试这个?
选择器的性能在浏览器之间会有很大差异。 例如,有querySelector
和querySelectorAll
(QSA)与没有。当没有QSA时,有getElementsByClassName
或没有。
选择器引擎需要执行的工作量会有所不同。
你可以用不同的方式写这个。 3 种方法,而不仅仅是 2 种:
1. $('accountDetailsTable').getElements('.toggler')
以上剖析为:
- 获取元素(1 次调用)。
- 从元素原型调用方法 getElements(或直接在旧 IE 中调用元素)
- 查找与类选择器匹配的所有子节点
这在浏览器中是一致的,因为它会获取一个根节点并从中调用方法。 如果没有 QSA,它将转到getElementsByClassName
或遍历所有childNodes
并筛选 className
属性,直到它有一个匹配项列表。性能方面,这在现代浏览器中会更糟,因为它需要链接,而方法 3 将是直接结果。
由于选择器在 JS 中的工作方式,与 CSS 不同 - 它是从左到右的,更合格的选择器可以提高性能,具有类似 .toggler
意味着当有一个较旧的浏览器时,它不必要地需要考虑树中的每个 DOMnode(文本节点除外)。 始终尽可能限定选择器,即 div.toggler
或a.toggler
.
2. $$('.toggler')
- 如果 QSA 可用,依靠浏览器返回内容(这里没有额外的黑客,如
:not
、:contains
、:has
或!
(反向组合器)。 - 如果没有 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并且您的项目涌入新开发人员时将继续工作。
只是我的两分钱,我知道你已经接受了答案。
在过去的两年里,我的内部MooTools知识变得有些生疏,但总的来说,我希望$$
选择器要快得多,因为它只需要运行一次元素。
为什么不试一试呢?请参阅此 JSfiddle:
粗略的 HTML:
<div id="accountDetailsTable">
<div id=".toggler">1</div>
<div id=".toggler">2</div>
<div id=".toggler">3</div>
</div>
JScript(请不要评论糟糕的代码,它只是为了演示功能):
window.addEvent('domready', function() {
var iter = 50000;
var tstart = new Date().getTime();
for (var i=0;i<iter;i++) {
var x = $('accountDetailsTable').getElements('.toggler');
}
var tend = new Date().getTime();
var tdur = tend - tstart;
console.log('$: ' + tdur + ' ms');
var tstart = new Date().getTime();
for (var i=0;i<iter;i++) {
var x = $$('.toggler');
}
var tend = new Date().getTime();
var tdur = tend - tstart;
console.log('$$: ' + tdur + ' ms');
});
也就是说,我对大约 50000 次迭代的测试大致得出了以下结果:
-
$('accountDetailsTable').getElements('.toggler')
: ~ 4秒 -
$$('.toggler')
: ~ 2秒
结果会因浏览器、元素等而异,因此这只是一个粗略的近似值。
也就是说,如果您在如此短的时间内拥有这么多选择器,您可能会感到不同。是的,应该考虑性能,如果您的应用程序中只有几个选择器,那么这并不重要。
我更喜欢$$()
,不是因为更好的性能,而是因为更好的可读性。
- 函数参数中的数据与指定变量之间的任何性能差异
- 提高JQuery的性能
- 使用正则表达式评估电子邮件地址时出现性能问题
- React:按键的性能提升
- 在Three.js中导出网格会提高性能吗
- 在javascript中搜索项目列表的性能
- 为什么在许多浏览器中drawImage()的性能略好于createPattern()
- JavaScript数组优化以提高性能
- React+Redux性能优化与组件ShouldUpdate
- 在循环中附加事件处理程序时出现浏览器性能问题
- JavaScript-===vs===运算符性能
- 超时功能的性能
- Pg承诺性能提升:在冲突中
- immutable.js与嵌套映射/对象的比较/相等性能
- NodeJ中的注释会影响性能吗
- 如果条件为循环-性能差异
- <脚本类型=“;模块“>负载性能
- 我应该如何将响应数据保存在对象(json)中以获得更好的操作和性能
- 错误编码的Adsense广告正在扼杀我的网站's的性能
- Mootools Selectors $ 或 $$.哪个性能更高