jQuery 中最佳性能的选择器?

Selector for best performance in jQuery?

我刚刚花了 2 个小时阅读有关 jQuery 选择器的在线指南和博客。每个人都说不同的话,而且他们中的每一个似乎都如此肯定。我需要 Whosebug 的专家意见。

$(' #my-id div.my-class ')

$(' #my-id .my-class ')

$(' div.my-class ')

$(' .my-class ')


<div id="my-id">
    <div class="..">
        <div class=".."> Awesome stuff! </div>
        <div class="my-class">
            <p> I like carrots! </p>
        </div>
    </div>
</div>

您认为哪个选择器最好?我还需要一个简短的解释,因为重写数千行代码处于危险之中。 它总是以这样或那样的方式发生,我只是不想重复两次

此外,如果我想得到 <p>,我应该给它一个 class 因为 jQuery 和 CSS 从右到左读取选择器吗?

是不是有太多class这样的事情,还是因为人们懒惰?


如果相同的规则适用于 CSS,请告诉我。一个字就够了

如果您想要的只是匹配 .my-class 的 DOM 个元素的所有实例,那么我认为您没有理由使用除以下以外的任何其他内容:

$('.my-class')

其他的都是更具体的选择器,如果你想将选择器缩小到不仅仅是 $('.my-class')

如果您真的想完全优化性能,那么首先使用 jQuery 可能不是理想的选择,因为 jQuery 初始化和 jQuery 对象的开销往往会使事情变慢。您使用 jQuery 是因为它可以快速编码并提供出色的跨浏览器支持和一系列有用的方法。您没有使用 jQuery 来优化性能。

如果你真的想比较你的四个 jQuery 选项的性能,那么你将不得不设计一组具有代表性的 HTML(其中必须包括很多其他的东西真正代表真实世界的情况),然后在一些基准测试工具(如 jsperf 和 运行 中测试你的每个选择器,这些工具在你关心的所有浏览器和你将要使用的 jQuery 版本中进行测试使用然后看看你是否可以得出一些特定的结论。

这听起来像是在尝试过早优化。首先尽可能简单地编写代码,只有当您实际测量到您有性能问题并且这是代码中性能瓶颈所在的地方时,才花时间优化性能。 99.99% 的时间,特定选择器的性能不会对您的代码产生丝毫影响。代码简单且不复杂。在您真正想要优化代码的那 0.01% 的时间里,您可能会非常关心性能,以至于您要么预先缓存元素列表,要么不在 jQuery 中编码,以便避免 jQuery 对象设置和开销。

这是一个 jsPerf:http://jsperf.com/jquery-selector-comparison-specificity/4。这表明在最新版本的 Chrome、Firefox 和 IE 中测试时选项之间的差异相对较小。 $('.my-class') 选项略有偏向。

作为参考,您会发现:

document.getElementsByClassName("my-class")

比任何 jQuery 选项快 50 倍。

这是 Chrome 中 jsperf 结果的屏幕截图:

结论

  1. 对于您尚未证明确实存在需要花时间优化的性能问题的正常编码,请使用符合您选择的最简单的选择器objective。

  2. 如果确实对性能很关键,请使用普通 Javascript,而不是 jQuery。

根据jQuery's Docs:

Beginning your selector with an ID is always best.

// Fast:
$( "#container div.robotarm" );

// Super-fast:
$( "#container" ).find( "div.robotarm" );

Be specific on the right-hand side of your selector, and less specific on the left.

// Unoptimized:
$( "div.data .gonzalez" );

// Optimized:
$( ".data td.gonzalez" );

Avoid Excessive Specificity

$( ".data table.attendees td.gonzalez" );

// Better: Drop the middle if possible.
$( ".data td.gonzalez" );

Avoid the Universal Selector. Selections that specify or imply that a match could be found anywhere can be very slow.

$( ".buttons > *" ); // Extremely expensive.
$( ".buttons" ).children(); // Much better.

$( ".category :radio" ); // Implied universal selection.
$( ".category *:radio" ); // Same thing, explicit now.
$( ".category input:radio" ); // Much better.

现在,综上所述...

注意这些东西并在可能的情况下进行优化是件好事,但实际上,其中许多或多或少最终会成为微优化。如果您正在寻找 trim 脂肪来提高性能,那么可能有更好的地方可以看。

加油...把我烧成异端...我不怕...

我做了一个基准测试,表明选择更具体的选择器更好。

我测试了这个 HTML :

<div id="my-id">
    <div class="grand">
        <div class="parent"> Awesome stuff! </div>
        <div class="my-class">
            <p> I like carrots! </p>
        </div>
    </div>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js'></script>

有 8 个不同的选择器:

$(' div#my-id div.grand div.parent div.my-class ').css("background-color", "#cccccc"); //case-1
$(' #my-id .grand .parent div.my-class ').css("background-color", "#cccccc"); //case-2
$(' #my-id .grand .parent .my-class ').css("background-color", "#cccccc"); //case-3
$(' div#my-id div.my-class ').css("background-color", "#cccccc"); //case-4
$(' #my-id div.my-class ').css("background-color", "#cccccc"); //case-5
$(' #my-id .my-class ').css("background-color", "#cccccc"); //case-6
$(' div.my-class ').css("background-color", "#cccccc"); //case-7
$(' .my-class ').css("background-color", "#cccccc"); //case-8

结果显示 case-1case-2case-3 比其他的要好。你可以看到结果 here.