具有上下文的jQuery选择器的性能

我正在阅读Brandon Aaron的这篇文章,关于jquery上下文如何帮助。 所以我想做一个自己的测试。 所以这就是我所做的。

  1. 在前面创建的“#context”中创建了一个id =“context”的DIV和嵌套的DIV,id =“holder”。

  2. 创建了深度为18的嵌套DIV,并将

    附加到其中,从而生成20个嵌套DIV

  3. 现在我测试了通过以下选择器访问“#holder”所花费的时间:
    一个。 $("#holder") // no context
    $("#holder", "#context") // with "#context" selector string
    C。 $("#holder", $("#context")) // sending jquery object each time with selector "#context"
    d。 $("#holder", $context) // where, var $context = $("#context"). Caching jquery obj
    记录了每次访问X = 1000次并开始和结束时间差的情况。 我发现所花时间:
    案例(a)是最不一致的28-32毫秒[jquery-1.3.2]
    情况(b)+(c)的最高时间分别为60-65毫秒和70-75毫秒
    情况(d)有40-50毫秒,有1或2个加标值。

这种基本检查有效吗? 您可以在JSBIN中使用JS代码。 [请告诉我如果我能改进这个测试一些如何]
如果是,那么这个“背景”真的有用吗?

#NOTE:在jsbin编辑模式下用jquery-1.4.2替换jquery-1.3.2,你会惊讶地发现数字突然增加:P

当你有一个更大的DOM搜索时,上下文确实有帮助。 搜索ID已经非常快,在这种情况下,上下文并没有真正帮助那么多。 当您通过标签名称或类别进行选择时,上下文可以真正发挥作用。

尝试这样的测试: http : //jsbin.com/aciji4/4

当你在DOM中增加项目数量时,你可以真正看到时间变得更好的上下文: http : //jsbin.com/aciji4/6

有意义的是,使用上下文需要更长的时间(而不是单独使用选择器),因为在内部,上下文使用.find()方法,所以从本质上讲,你所做的只是

 $('#context').find('#holder'); 

我主要将其视为一种更简单的方法来识别上下文发生变化的事件和迭代器中的元素

 $('.holder', this) 

比…更漂亮

 $(this).find('.holder') 

#ID选择器依赖于浏览器本机document.getElementById。 无论怎样,它都会很快。

在有和没有上下文的情况下尝试使用div.class [attribute = value]这样的选择器。 例如*,您可以使用此选择器选择右侧的“相关”问题链接:

 // Selects anchor elements with href's beginning with /questions/ $('a[href^=/questions/]') 

但是,限制选择器引擎必须迭代的锚元素数量更快,评估相对昂贵的文本匹配:

 $('a[href^=/questions/]', '.related') 

*为了便于讨论,忽略了这些链接上明显更容易的.question-hyperlink类。

对于它的价值, $context = $("#context")仍然使用jQuery对象,然后必须将其转换为DOM对象。

如果你使用$context = $("#context")[0]你会发现它的运行速度与第一次测试一样快。

在重构代码之前要小心。 正如#NOTE编写的那样,jQuery自1.4以来的工作方式完全不同。 最新版本可能包含更多优化。

我修改了上面的jsbin代码以获得最近的jQuery,并添加了一些其他案例。 你会看到,现在只有那三(2,3,6)个案例得到了性能损失,每轮创建一个jQuery对象。 rest在同一时间运行。

你可以在这里找到修改后的版本: http : //jsbin.com/aciji4/63/

我已经把JSBin代码放到了jsPerf测试中

$ context.find(’。holder’)的速度是其最接近的竞争对手$(’。holder’,$ context)的两倍,并且比使用的任何其他选择器快十倍

总之,缓存选择器并使用.find()以获得最佳性能