选择器应该具体如何?

时间:2011-07-26 22:05:32

标签: jquery jquery-selectors

我有一个关于jQuery的一般问题。假设我有以下代码:

<div id="container">
    <ul>
        <li>1</li>
        <li class="target">2</li>
        <li>3</li>
    </ul>
</div>

选择target元素的最佳,最快的方法是什么?

$('div#container ul li.target')

$('#container .target')

$('li.target')

或者这更快:

$('.target')

我想知道,实现这一目标的最佳方式是什么?你可以说越具体越好,但是过于具体会减慢这个过程,我猜。 class方法也是“慢”,但差别不大,或者我错了?

5 个答案:

答案 0 :(得分:6)

对于此示例,$('.target')是最快的。 JQuery已经找到了遍历算法;)

证明:http://jsperf.com/jquery-selector-speed-tests

答案 1 :(得分:2)

  • 我不需要额外的描述符。 #id优于div#id
  • Sizzle通常从右到左工作(显然左边有一个id上下文,它首先搜索),所以最好更具体一点 正确的(这样可以减少结果,减少二次检查 跑)。但是现代浏览器的实现 querySelectorAll可能并不坚持,所以真的很难说。

总的来说,这很难说,而且大部分变化都是微观优化。你做了多少选择它会产生如此大的影响?更重要的是,如果您的执行速度很慢,您是否对其进行了分析并澄清了瓶颈在哪里?如果没有,你可能会非常努力地挤压,并且不会从这个中获得更多的柠檬汁。

最后,你必须意识到人们向你投掷的jsperfs或其他基准,这对于一般情况来说是不确定的。这一切都非常具体。也许你的DOM很简单,将来可能会更复杂。你需要测试自己的案例。另一个答案链接到一个解决方案,其结论我完全不同意。在那里,DOM有4个元素,在实际情况下,它可能有4000个,这意味着所有的赌注都已关闭。

答案 2 :(得分:1)

在新的浏览器中它们并不重要,它们都是相同的,但在较旧的浏览器中:

$('#container li.target');

对我来说似乎最好。使用getElementById()直接找到#container,然后将getElementsByTagName()用于li,最后jquery手动检查结果上的.target类。

答案 3 :(得分:1)

http://jsperf.com/jquery-selector-speed-tests/3

如果您在IE7中进行测试,您会发现$(.target)的建议不正确。您希望针对我认为支持的最差浏览器进行优化,这意味着$('#container').find('.target')实际上比当前建议更快。

修改: http://jsperf.com/jquery-selector-speed-tests/7表明在很多情况下.target不够用,因为您需要更具体的上下文。

答案 4 :(得分:0)

嗯,这取决于你想要达到的目标。

好的,如果您使用这样的选择器[id * ='someid'],jQuery将查找与特定选择器匹配的完整DOM。所以这需要花费很多时间。我通过为该特定元素添加一个类(它是唯一的)来解决这个问题,或者我必须确保我可以通过id获取该元素。

另一个例子,如果您要使用多个选择器(这与您的问题有关),它将读取您在选择器中所做的每个选择。我们以第一个为例:

$('div#container ul li.target')

第一个jQuery将匹配每个具有id容器的div。在每个容器之后,jQuery将搜索UL列表。之后,它将搜索具有类目标的LI。在这种特殊情况下,它将通过DOM读取3次(但仍然在较小的子集中,并且不要忘记它从上到下读取)。

基于这个解释,最后一个

$('.target')

将是最快的。为什么? jQuery需要在DOM中查找一次匹配选择器。