带有 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 事件处理程序?

jQuery 选择器的性能特征与 CSS 选择器的性能特征有何不同?

jquery 选择器与 css3 选择器的性能

使用带有 jquery 选择器的变量

带有选择器的 JQuery 引用变量,错误的数据

JQuery选择器