带有 ID 的 jQuery 选择器的性能
Posted
技术标签:
【中文标题】带有 ID 的 jQuery 选择器的性能【英文标题】:Performance of jQuery Selectors with ID 【发布时间】:2012-11-10 14:26:55 【问题描述】:我知道在 jQuery 中如果我们使用ID
来选择元素,它是如此高效。我对这个选择器有疑问:
请考虑这 3 个选择器:
$('#MyElement')
$('#Mytbl #MyElement')
$('#Mytbl .MyClass')
哪个更快,为什么?如何检查在 jQuery 中选择我的元素所用的时间?
【问题讨论】:
【参考方案1】:直接 ID 选择器总是是最快的。
我根据您的问题创建了一个简单的测试用例...
http://jsperf.com/selector-test-id-id-id-id-class
选择嵌套 ID 是错误的,因为如果一个 ID 是唯一的(它应该是唯一的),那么它是否嵌套并不重要。
【讨论】:
不客气,这是一个真的好资源!在从代码中获得最佳性能方面有很大帮助 - 但这应该牢记在心,直到性能成为问题,或者当您处于开发的最后完善阶段。 我不知道jsperf可以使用DOM o.o测试性能【参考方案2】:这是在一些 javascript 调用之间停止时间的方法
selectorTimes = [];
var start = new Date().getTime();
$('#MyElement')
selectorTimes.push(new Date().getTime()-start);
start = new Date().getTime()
$('#Mytbl #MyElement')
selectorTimes.push(new Date().getTime()-start);
start = new Date().getTime()
$('#Mytbl .MyClass')
selectorTimes.push(new Date().getTime()-start);
console.log(selectorTimes);
我认为第二个选择器效率不高,如果你有一个domid直接选择这个: $('#MyElement')
【讨论】:
为什么不直接使用 jsperf.com? +1 为我们提供了测量工具,尽管您可能需要遍历每个 1000 次左右才能获得对时间的任何意义? @StuartLC:是的:console.log(selectorTimes); --> [0, 0, 0]
【参考方案3】:
第一个是最快的,因为它只有 1 个属性可供查找。然而,
document.getElementById("MyElement")
甚至更快。它是原生 javascript,与 jQuery 不同,浏览器立即知道您想要做什么,而不必首先运行大量 jQuery 代码来找出您要查找的内容。
您可以使用jsPerf 运行速度测试,比较功能:Test Case。结果:
$('#MyElement')
Ops/sec: 967,509
92% slower
$('#Mytbl #MyElement')
Ops/sec: 83,837
99% slower
$('#Mytbl .MyClass')
Ops/sec: 49,413
100% slower
document.getElementById("MyElement")
Ops/sec: 10,857,632
fastest
不出所料,原生 getter 是最快的,其次是只有 1 个选择器的 jQuery getter,速度不到原生速度的 10%。带有 2 个参数的 jQuery getter 甚至无法接近原生代码的每秒操作数,尤其是类选择器,因为与 ID 相比,类通常应用于多个元素。 (原生 ID 选择器在找到一个元素后停止搜索,我不确定 jQuery 是否也这样做。)
【讨论】:
我刚刚运行了自己的 jsperf 来检查这一点,与 jQuery 相比,document.getElementById 获得了同样出色的结果。性能提升了惊人的 5 倍。 jsperf.com/classversusid【参考方案4】:给你。请参阅每个示例顶部的 cmets:
//fastest because it is just one id lookup: document.getElementById("MyElement") with no further processing.
$('#MyElement')
//a little slower. JQuery interprets selectors from right to left so it first looks up for #MyElement and then checks if it is hosted in #Mytbl
$('#Mytbl #MyElement')
//the slowest of all. JQuery interprets selectors from right to left so it first finds all elements with .MyClass as their class and then searches for those hosted in #Mytbl.
$('#Mytbl .MyClass')
如果可以,请始终只使用 id(如第一个示例),但如果您必须将多个选择器和类链接在一起,请尝试将最严格的放在右侧。例如身份证。因为 JQuery 从右到左解释选择器。
【讨论】:
【参考方案5】:几件事:
更多选择器 = 更慢的搜索。如果您可以使用更少的谓词获得所需的结果,请这样做。 通过 ID 获取元素比通过类获取更快。 getElementById 是 JavaScript 的一个核心函数,因为它被频繁使用而进行了大量优化。尽可能利用这一点。 空间选择器 (' ') 比子选择器 ('>') 成本高得多。如果您可以使用子选择器,请这样做。这些规则适用于 CSS,就像它们适用于 JavaScript 和 jQuery。
【讨论】:
【参考方案6】:另外,如果你需要嵌套选择器,使用 $().find().find() 会更快
http://jsperf.com/selector-test-id-id-id-id-class/2
$('#Mytbl .MyClass')
$('#Mytbl').find('.MyClass')
后者大约快 65%。
【讨论】:
【参考方案7】:显然第一个,$("#MyElement")
比其他 2 个快。
使用 id 访问元素总是更快,但有时我们必须在某个容器中找到一些元素。在这种情况下,我们更喜欢.find()
或.filter()
(视情况而定)。
选择器之间的区别取决于浏览器到浏览器。例如如果你通过 IE 上的类访问它会比 FF 慢。使用类而不是 ID 访问元素时,FF 更快。
在您的第二个示例中,即$("#mytbl #MyElement")
,您在#mytbl
下找到#MyElement
,这是合法但不合适的方式。由于您已经知道元素的 ID(假设您的页面上只有一个具有此 ID 的元素)所以最好使用$("#MyElement")
。 $("#mytbl #MyElement")
将首先读取#mytbl 并遍历以在其下找到#MyElement,因此既耗时又慢。
要测试不同的情况,您可以编写小型 sn-p 以在循环中读取/访问至少 10000 个元素,否则很难确定哪种方式更快。
【讨论】:
【参考方案8】:最快的将是:
$('#Mytbl', '#MytblContainer' );
因为在这种情况下,jquery 不必搜索整个 dom 树来查找“#Mytbl”。它只会在给定的范围内搜索。 IE 它只会在 '#MytblContainer' 中搜索。
【讨论】:
它必须首先“搜索整个范围”以查找#MytblContainer
。不过,jQuery 不会循环遍历 DOM。它只使用document.getElementBy<x>();
确保您将 html 分配到不同的部分,例如页眉、页脚、内容......【参考方案9】:
我会说第一个是最快的,因为您只是在搜索一个 id。
还有
$('#Mytbl .MyClass')
是最慢的,因为您没有指定具有“MyClass”类的元素的类型
【讨论】:
以上是关于带有 ID 的 jQuery 选择器的性能的主要内容,如果未能解决你的问题,请参考以下文章
如何使用类选择器覆盖 id 选择器的 jQuery 事件处理程序?