【问题标题】:Jquery element+class selector performancejQuery元素+类选择器性能
【发布时间】:2012-07-26 18:56:16
【问题描述】:

我希望 $('#childDiv2 .txtClass')$('#childDiv2 input.txtClass') 在选择 <input type="text" id="txtID" class="txtClass"/> 元素时表现更好。但据此performance analysis $('.txtClass'); 是其中最好的选择器。我正在使用 JQuery 1.7.2 有人对此有解释吗?

HTML

<div class="childDiv2">
    <input type="text" id="txtID" class="txtClass"/>
    <p class="child">Blah Blah Blah</p>
</div>​

JS

$('.txtClass');
$('#childDiv2 .txtClass')
$('#childDiv2 > .txtClass')
$('input.txtClass')
$('#childDiv2 input.txtClass')

【问题讨论】:

  • 因为 id 必须是唯一的,所以最快的方法是 $("#txtID")
  • 我关心的是按班级场景选择?
  • 好问题。我没有答案,但很奇怪即使给出上下文 $('.txtClass', '#childDiv2') 仍然比类选择器慢。

标签: jquery jquery-selectors performance


【解决方案1】:

现代浏览器公开了一个非常有效的getElementsByClassName() 方法,它返回具有给定类的元素。这就是为什么在您的情况下单个类选择器更快的原因。

详细说明您的示例:

$(".txtClass")                  =>  getElementsByClassName()

$("#childDiv2 .txtClass")       =>  getElementById(),
                                    then getElementsByClassName()

$("#childDiv2 > .txtClass")     =>  getElementById(),
                                    then iterate over children and check class

$("input.txtClass")             =>  getElementsByTagName(),
                                    then iterate over results and check class

$("#childDiv2 input.txtClass")  =>  getElementById(),
                                    then getElementsByTagName(),
                                    then iterate over results and check class

如您所见,第一种形式在现代浏览器上是最快的,这是很合乎逻辑的。

【讨论】:

  • 所以我可以说几乎所有在网上找到的 jquery 性能教程都是不正确的。甚至像 Addy Osmani 之类的一些 jquery 家伙的教程@
  • @Lanka,也许不是不正确,只是过时。技术在进步,今天最好的性能建议明年很可能是错误的。另一方面,基准会为您提供最新的数字。
  • 是的,这是正确的。其实我之前的评论是错的。那家伙已经在幻灯片中解释过了。
  • @FrédéricHamidi 我认为您错误地暗示您的答案是阅读的方式是从左到右,而实际上在所有现代浏览器中它是从右到左使用 getElementById (), "then" getElementsByTagName() 等。操作就是这些,只是它们不会按那个顺序发生。
  • @daremkd,它不完全是 RTL(请参阅this related answer 下的 cmets)。此外,它在应用样式时完成,即目标是找到与给定元素匹配的所有选择器querySelector*() 尤其是 Sizzle 引擎的目标不同(他们的目标是找到与给定选择器匹配的所有元素),我怀疑他们会以性能为代价选择 RTL(尤其是 Sizzle )。
【解决方案2】:
var obj = document.getElementById("childDiv");
xxx = obj.getElementsByClassName("txtClass");

快 30 倍。

http://jsperf.com/selectors-perf/6

【讨论】:

    【解决方案3】:

    CSS 选择器从右到左解析。所以你的例子

    $('#childDiv2 .txtClass')
    

    将采取两个动作来完成。首先找到类txtClass的所有元素。然后检查每个元素是否是 ID 为 childDiv2 的元素的子元素。

    $('.txtClass')
    

    这个选择器只会执行一项操作。查找类txtClass的所有元素

    在 css-tricks.com 上查看this article

    【讨论】:

    • 据我所知,优化此查询。所以它的工作方式与你的解释不同。首先选择childDiv2,然后在它的children中搜索txtClass。
    • 实际上,显示的第一行代码需要检查每个 .txtClass 元素以查看它是否是#childDiv2 的后代。这需要检查每个 .txtClass 的所有祖先。
    【解决方案4】:

    看起来它还取决于类型元素中具有类的元素的密度。

    我使用 JQuery 1.10.1 使用 Google Chrome 版本 30.0.1599.69 运行了测试。随意在其他浏览器上尝试和/或使用其他 JQuery 版本。

    我尝试运行以下测试:

    1. 稀疏(10% 的 div 有类)link to the test on jsbin

    2. 密集(90% 的 div 有类)link to the test on jsbin

    看起来在密集情况div.class获胜,但在稀疏情况.class获胜。

    【讨论】:

    • 就像提到密集/稀疏的 cmets 一样,这经常被忽略。如果可以的话,除了使用 id 之外没有灵丹妙药。
    猜你喜欢
    • 2011-09-04
    • 2013-01-04
    • 2023-01-11
    • 2011-01-14
    • 1970-01-01
    • 2010-11-27
    • 2011-06-23
    相关资源
    最近更新 更多