代码之家  ›  专栏  ›  技术社区  ›  JonoW

jQuery选择器性能

  •  5
  • JonoW  · 技术社区  · 15 年前

    我在性能上有很大的变化,这取决于我如何表达选择器。例如,看看这两个选择器,它们选择完全相同的元素:

    A) someTableRow.find("td.someColumnClass").find("span.editMode").find("input")
    B) someTableRow.find("td.someColumnClass span.editMode input")
    

    我希望b)更快,因为只有一个调用,但实际上我发现a)执行速度大约是8倍。我不知道为什么,有人知道吗?谢谢

    6 回复  |  直到 15 年前
        1
  •  14
  •   Community Nick Dandoulakis    7 年前

    假设您至少使用了jquery 1.3(即添加了sizzle),那么您看到的性能是由于DOM被遍历的变化造成的。从 here :

    截至并包括jquery 1.2.6 选择引擎在“自上而下”中工作 (或“从左到右”)的方式。JQuery 1.3 x Sizzle ,jquery嵌入)引入了“自下而上”(或 “从右到左”)查询方法 DOM。

    在第二个例子中( "td.someColumnClass span.editMode input" ,sizzle有效地做到了:

    1. 全部得到 input 内部元素 someTableRow
    2. 对于每一个 输入 元素,遍历其祖先树 span 元素与 class="editMode" . 去除 输入 没有这些祖先的元素
    3. 对于每一个 span.editMode 元素,遍历其祖先树 td 元素与 class="someColumnClass" .删除 输入 没有这些祖先的元素

    但是,在第一个示例中,每个调用都明确限定了每个步骤 find() ,定义上下文并遍历 向下 从那里。您正在实施“自上而下”的方法。它相当于在每个步骤的上下文中传递,即 generally considered a performance booster :

    $('input', $('span.editMode', $('td.someColumnClass', someTableRow)))
    
        2
  •  2
  •   Josh Wright    15 年前

    因为你在减少搜索的上下文。

    在案例B中,它必须搜索每个DOM元素,以查看它是否满足条件。

    在案例A中,is可以快速决定忽略任何不是“td.someColumnClass”的内容,然后它可以获取dom的子集并忽略任何不在“span.editmode”中的内容。所以现在它有一组小得多的元素要搜索来查找“input”。

        3
  •  1
  •   Sampson    15 年前

    A是更多的电话,但更简单。B是一个电话,但更复杂。在这种情况下,呼叫的复杂性极大地影响了呼叫的数量。

        4
  •  1
  •   Daniel Elliott    15 年前

    在我的经验中,jquery处理selector的方式与css稍有不同。

    正如乔希指出的,减少搜索的上下文是关键。

    我发现使用两个参数选择器非常快

    如何比较速度?

    你不需要这里所有的var,这只是为了清楚我在做什么。

    var columnClasses = $('.someColumnClass');
    var tableCell = $('td', columnclasses);
    var editMode = $('.editmode', tableCell);
    var spanInside = $('span', editMode);
    var inputFinally = $('input', spanInside);
    

    仁慈,

        5
  •  1
  •   Andreas Grabner    15 年前

    我自己做了一些关于jQuerySelector性能的研究。一个大问题是在Internet Explorer上按类名查找。IE不支持getElementsByClassName,因此jQuery和其他框架通过迭代所有DOM元素在JavaScript中“重新实现”它。 查看以下分析日志 jQuery Selector Performance

        6
  •  -1
  •   bryanbcook    15 年前

    这里有一篇关于选择器性能的非常有趣的文章: http://blogs.atlassian.com/developer/2009/08/jquery_bondage.html

    在本文中,作者展示了一个“bind”jquery扩展,它显示了函数被计算的次数。