【问题标题】:Which jQuery selection method is faster?哪种 jQuery 选择方法更快?
【发布时间】:2011-08-16 22:58:14
【问题描述】:

我想知道在使用 jQuery 进行选择时使用 context 参数与使用普通的 CSS 范围选择器相比是否有任何优势。

假设我有这个 html:

<div class="contacts">
    <h1>All contacts</h1>
    <div class="contact new">
        <p class="name">Jim Jones</p>
        <p class="phone">(555) 555-1212</p>
    </div>
    <div class="contact new">
        <p class="name">Bob Smith</p>
        <p class="phone">(555) 555-1213</p>
    </div>
    <div class="contact new">
        <p class="name">Dave Baker</p>
        <p class="phone">(555) 555-1214</p>
    </div>
    <div class="contact">
        <p class="name">Pete Harrison</p>
        <p class="phone">(555) 555-1215</p>
    </div>
    <div class="contact">
        <p class="name">George Donald</p>
        <p class="phone">(555) 555-1216</p>
    </div>
    <div class="contact">
        <p class="name">Chris Root</p>
        <p class="phone">(555) 555-1217</p>
    </div>
</div>

如果我想从联系人 div 中获取所有新联系人(由“新”类标记),哪种方法更快、扩展性更好等等?

$('.contacts .new');

或者

$('.new', '.contacts');

jsFiddle

更新

答案和 cmets 中散布着很多很棒的信息。总结要点,在大多数浏览器中,当有多个 .contacts div 时,单个选择器的伸缩性更好。在大多数浏览器中,两个选择器上下文方法更快,只有一个 .contacts div 存在。

值得一提的是,我们可以使用一种方法在带有 id 的元素中进行选择。

$('p:first', '#chapter2'); // get the first paragraph from chapter 2

对于我们从可能很大的一组元素中进行选择的实例,请使用单一选择器方法。

$('.chapter p:first-child'); // get the first paragraph from all chapters

【问题讨论】:

  • 您在测试它们时发现了什么?
  • 有时询问更容易,您最终会获得更多信息。例如,在这里我了解到 jsperf 存在。 :)

标签: jquery performance


【解决方案1】:

在所有(我的)赔率下,似乎 2 号是最快的。

查看it here

【讨论】:

  • +1(如果我今天没有达到我的极限)我很惊讶差异也如此之大。
  • 真的吗?我认为单个选择器最快:S
  • 我的 2 美分为什么会这样:jQuery 可以检测到每个选择器都是一个简单的类查找,因此它将两者都委托给高度优化的浏览器函数 getElementsByClassName。当它们在一个字符串中时,它无法进行这样的优化,并会使用querySelectorAll 或它自己的方法来找到它。
  • 我刚刚在 Opera 中运行它。检查结果。这是我运行的第三次测试,表明他们有一个高度优化的querySelectorAll
  • 谢谢,巴勃罗!这正是我所追求的那种信息。感谢您在此过程中让我了解 jsPerf。
【解决方案2】:

$('.contacts .new') 理论上应该可以更好地扩展,因为它只对选择器引擎进行一次调用。对于$('.new', '.contacts'),至少会调用两次选择器函数——首先获取类名为.contacts的所有元素,然后进一步调用返回的每个.contacts元素。

总而言之,一旦更多的.contacts 元素被扔进HTML 中,第二种方法需要一个循环,它会显着减慢。如果您不想拥有更多 .contact 元素,则应该使用更快的 ID。

【讨论】:

    【解决方案3】:

    IIRC,$('.foo', '.bar') 代表$('.bar').find('.foo'),所以第二个应该更快。

    $('.foo', '.bar')$('.foo .bar') 快的原因是它作为原生getElementsByClassName 被嘶嘶声执行。在执行任何复杂逻辑之前,很早就在代码中检查了仅包含单个类名的选择器的情况。

    更新:就像我想的那样,使用 find() 稍微快一点:http://jsperf.com/jquery-selection-method/2

    更新 2:我在 jQuery 的代码中查找了它 - $('.foo', '.bar') 确实委托给 $('.bar').find('.foo') - https://github.com/jquery/jquery/blob/master/src/core.js#L171

    【讨论】:

      【解决方案4】:

      在您的两个示例中,第一个选择器可能会更快。但是,如果将上下文分配给变量,则使用第二种方法会快得多。

      contacts = $('div.contacts');
      $('.new', contacts);
      

      您可以在http://jsperf.com/jquery-context-with-tagname 查看结果。如果您有一个较大的 HTML 文档,在类前面加上标签名称也可能会产生更好的性能。

      【讨论】:

        【解决方案5】:

        第二个是未记录的,所以你根本不应该使用它。

        context 参数应该是:

        用作上下文的 DOM 元素、文档或 jQuery

        参考:http://api.jquery.com/jQuery/

        字符串两者都不是。

        所以,你应该在使用 at 作为上下文之前从选择器创建一个 jQuery 对象:

        $('.new', $('.contacts'));
        

        当您进行两次 jQuery 调用时,应该会稍微慢一些。但是,这两种表达方式基本上都做同样的工作,所以差异应该不会那么大。

        编辑:

        测试方法如何扩展:http://jsperf.com/jquery-selection-method/4

        显示不同浏览器的性能不同。当您有一个 .contacts 时,大多数浏览器中的单个选择器会较慢,但 Opera 除外,它的速度非常快。使用多个 .contacts 元素时,单个选择器可以更好地扩展。

        【讨论】:

        • 很好,我在 Pablo 的帖子中添加了那个测试用例,它应该是内联的。所以这确实表明它现在正在使用 getElementByClassName,这将比 queryall 更快。
        • 您的可扩展性测试似乎没有实际意义,考虑到如果只有一个 .contacts 元素,ID 将是更好的选择(例如 $('.new', '#contacts'))并且应该更快。如果有多个.contacts 元素,则第二种方法可能无法很好地扩展。
        • @Andy E:你说得有道理。我将测试编辑为具有多个 .contacts 元素,并且单个选择器处理得更好。
        【解决方案6】:

        http://jsfiddle.net/cvWA7/1/

        我得到的结果是第一个选择器$('.contacts .new') 大约快了 22%。

        更新 有趣的是,Pablo 得到了相互矛盾的结果。我想知道我的测试是否有问题。

        更新 2 这是在 Chrome 13 上运行的

        【讨论】:

        • 性能差异很大,具体取决于您测试的浏览器。例如,在 Opera 中,单个选择器的速度大约快 200%。
        猜你喜欢
        • 2016-04-17
        • 1970-01-01
        • 2021-11-15
        • 1970-01-01
        • 2019-11-22
        • 1970-01-01
        • 2011-03-12
        • 2021-08-03
        • 2011-05-14
        相关资源
        最近更新 更多