我想知道前几天在jQuery中输入你的选择器时,如果你指定你的选择器非常具体或非常松散,它会对性能产生影响。
E.g
$('$myId .someElement')
或
$('table#myId > tbody > tr > td > div.someElement');
第二个选项是否会更快或者差异是否可以忽略,例如,当你需要反复找到相同的元素时,.each()
。
答案 0 :(得分:5)
更新2:
总结一些其他评论。答案是取决于。
jQuery的选择器引擎Sizzle以与CSS相同的方式评估选择器:from right to left。所以一般来说,最好是在右侧非常具体,在左侧不太具体。
但它还取决于HTML的结构以及您想要查找的元素的分散程度。
所以,如果你有
a
|
...
|
b
-----------------
| |
d d d c c c c c c c c c c c c c c c c c c c
然后更具体的是更快$('a b > c')
,因为您使用b > c
提前减少了元素集,并且不必检查每个a
的{{1}}继承
然而,如果你有
c
然后 a
|
...
|
b
-----------------
| |
e e e e e e e e d d c c c c c c e e e e e e
会更快,因为选择器更简单,并且在这种情况下测试$('a c')
作为c
的孩子是多余的(当然你甚至可以{{1} }})。
原始回答:
无论哪一个更快,如果你必须反复访问一个元素,存储对它的引用:
b
The first selector seems to be a bit faster(在Chrome 8中)。
在较新的浏览器中(支持$('c')
),差异可能不如不支持它的浏览器那么大。
<强>更新强>
我认为这主要取决于jQuery可以使用多少内置方法。因此假设var $element = $('#myId .someElement');
$('some other selector').each(function() {
// access $element here
});
不可用,第一个选择器可以转换为
querySelectorAll
对于第二个选择器,jQuery必须另外检查一个元素是否确实是一个孩子。即还有一些处理过程。
答案 1 :(得分:4)
我会选择:
$('.someElement', '#myId')
由于getElementById是最快的选择器操作,因此您首先过滤内容然后搜索该类。选择器越少,选择的速度就越快(取决于使用后代或子选择器 - 检查注释!)。 Test基于@Felix测试用例。
编辑:所以要加强这个答案。基于jQuery documentation:
默认情况下,选择器会执行它们的操作 从DOM开始搜索 文档根目录。但是,一个 可以给出替代上下文 使用可选的秒搜索 $()函数的参数。
因此,当您提供第二个参数(上下文)时,jQuery将首先搜索该元素,然后在其中进行搜索,以便从以下位置进行翻译:
$('.someElement', '#myId')
致:
$('#myId').find('.someElement')
现在的诀窍是,尝试找到实际拥有ID的元素的最近容器并将其设置为 context ,因为ID选择是 最快 即可。现在你会说,为什么不使用第二个已翻译过的,我实际上并不会那么在意,因为第一个更干净而且速度并不慢:
$('.someElement', '#myId') $('#myId').find('.someElement')
Chrome 8.0.552 36,527 37,400
Firefox 3.6.13 17,632 19,155
答案 2 :(得分:0)
'#myid .myclass'
1)找到所有具有类myclass
的元素
2)对于每个这样的元素,如果你到达#myid
祖先,就去它的祖先链并停下来。如果没有这样的祖先,请丢弃该元素。
现在,很可能浏览器会优化此过程,例如:
1)找到#myid
元素
2)找到所有具有类myclass
并且是#myid
元素的后代
table#myid > tbody > tr > td > div.mylcass
请注意,为ID选择器添加类型选择器前缀无效,因为ID在文档中是唯一的。
#myid > tbody > tr > td > div.mylcass
使用类型选择器为类选择器添加前缀在性能方面更好。因此,如果您知道元素的类型,建议您进行设置。
我不确定那些儿童选择器。我想如果你使用它们会更快。但要快多少?可能是可以忽略的?而且,它看起来很难看。
考虑一下:
#myid td > div.myclass
如果#myid
是一个表元素,并且您没有嵌套表,则此选择器应该与第二个选择器一样快。我会用这个。
答案 3 :(得分:-1)
第二个会更快,因为它确切知道每个步骤要查找的内容。
在这个例子中:
$('table#myId > tbody > tr > td > div.someElement');
如果没有tbody,或没有tr,或没有td(等),它可能会立即从搜索中删除。此外,每个后续步骤都将缩小搜索范围(例如:不在<thead>
内搜索)。与此示例相比:
$('#myId .someElement')
这必须扫描 #myId
的每个子元素。
编辑:正如FelixKing指出的那样,您的第一个示例$('#myId .someElement')
实际上是更快。只是勉强,但仍然,更快,所以我想我应该回应。使用子选择器(>
)而不是后代选择器(空格)是最快的遍历方法,因为可能的元素集要少得多。但是,现代浏览器具有高度优化的内置方法,jQuery有时可以使用这些方法,实际上减少了执行时间。因此,正如在这种特殊情况下所看到的那样,“更差”的实际上更好,因为浏览器针对执行特定查询进行了更好的优化。然而,一般情况下,原始点仍然存在,特别是如果您使用的东西无法通过浏览器进行优化(例如,自定义选择器)。