jQuery选择器性能

jQuery选择器性能,jquery,performance,css-selectors,Jquery,Performance,Css Selectors,根据我表达选择器的方式,我的性能有很大的变化。例如,看看这两个选择器,它们选择完全相同的元素: A) someTableRow.find("td.someColumnClass").find("span.editMode").find("input") B) someTableRow.find("td.someColumnClass span.editMode input") 我希望B)更快,因为只有1个调用,但事实上我发现A)执行速度大约快8倍。我不知道为什么,有人知道吗?谢谢A是更多的电话

根据我表达选择器的方式,我的性能有很大的变化。例如,看看这两个选择器,它们选择完全相同的元素:

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

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

A是更多的电话,但更简单。B是一个电话,但更复杂。在这种情况下,调用的复杂性大大超过了调用的数量。

因为您正在减少搜索的上下文

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


在案例A中,is可以快速决定忽略任何不是“td.someColumnClass”的内容,然后它可以获取DOM的子集并忽略任何不是“span.editMode”的内容。因此,现在搜索“输入”的元素要少得多。

这里有一篇关于选择器性能的非常有趣的文章:


在本文中,作者展示了一个“bind”jQuery扩展,它显示了函数的求值次数。

根据我的经验,jQuery处理选择器的方式与CSS略有不同

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

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

这在速度方面如何比较

你不需要这里所有的VAR,只是想弄清楚我在做什么

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


Dan

假设您至少使用了jQuery 1.3(即添加了Sizzle),那么您看到的性能是由于遍历DOM的更改造成的。发件人:

直到并包括jQuery 1.2.6 选择引擎以“自上而下”的方式工作 (或“从左到右”)的方式。jQuery 1.3.x(即jQuery嵌入的)引入了“自底向上”(或 “从右到左”)查询方法 大教堂

在第二个示例(
“td.someColumnClass span.editMode input”
)中,Sizzle有效地做到了这一点:

  • 获取
    someTableRow中的所有
    input
    元素
  • 对于找到的每个
    input
    元素,使用
    class=“editMode”
    遍历其
    span
    元素的祖先树。删除没有这些祖先的
    input
    元素
  • 对于找到的每个
    span.editMode
    元素,使用
    class=“someColumnClass”
    遍历其
    td
    元素的祖先树。删除没有这些祖先的
    input
    元素
  • 然而,在第一个示例中,您使用对
    find()
    的每次调用来明确限定每个步骤,定义一个上下文并从那里向下遍历。您正在实施“自上而下”的方法。这相当于在每个步骤中传递上下文,即:


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

    的分析博客,它如何“快速决定忽略…”而不检查someTableRow的整个DOM子级?它们都检查同一整套子元素,其中一个使用someColumnClass查找td,然后使用editMode解析该列表中的跨度,然后解析该列表中的输入。另一个在初始列表的相同搜索中查找所有三个条件。由于这两个选择器的含义相同,我不明白为什么jQuery不能在这两种情况下使用相同的策略。询问者指的是
    find()
    ,而不是
    bind()
    。感谢crescentfresh,这是有意义的。实际上,我们刚刚从1.2.6迁移到1.3.2,我很困惑为什么一些以前相当快的选择器变得更慢(大多数更快)。问题-在每个点上传递上下文或使用链式find()调用哪个更快?它们实际上是等价的$('foo','bar')实际上被重新路由到$('bar')。在jQuery的肚子中查找('foo')。我想显式地调用find()可以节省几个CPU周期,但没有什么可以忽略的。做你的团队最容易理解的事情。我觉得很可读;)酷,我觉得find()对我来说更直观,所以我会使用它
    $('input', $('span.editMode', $('td.someColumnClass', someTableRow)))