jQuery选择器性能

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

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

我希望B)能够更快,因为只有1次调用,但事实上我发现A)的执行速度提高了大约8倍。 我不知道为什么,任何人都有任何见解? 谢谢

假设您至少使用jQuery 1.3(即添加了Sizzle),您看到的性能是由于遍历DOM的变化。 从这里 :

直到并包括jQuery 1.2.6,选择器引擎以“自上而下”(或“从左到右”)的方式工作。 jQuery 1.3.x(即, jizz嵌入的Sizzle )引入了一种“自下而上”(或“从右到左”)查询DOM的方法。

在你的第二个例子中( "td.someColumnClass span.editMode input" ),Sizzle有效地做到了这一点:

  1. 获取someTableRow所有input元素
  2. 对于找到的每个input元素,使用class="editMode"遍历其span元素的span元素。 删除没有这些祖先的input元素
  3. 对于找到的每个span.editMode元素,遍历其祖先树以获取具有class="someColumnClass" td元素。 删除没有这些祖先的input元素

然而,在你的第一个例子中,你通过每次调用find() ,定义一个上下文并从那里向下遍历,明确地限定每一步。 您正在执行“自上而下”的方法。 它相当于在每个步骤传递一个上下文, 通常被认为是一个性能助推器 :

 $('input', $('span.editMode', $('td.someColumnClass', someTableRow))) 

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

在情况B中,它必须搜索每个DOM元素以查看它是否符合标准。

如果A,可以快速决定忽略任何不是“td.someColumnClass”的东西,那么它可以占用DOM的子集并忽略“span.editMode”中没有的任何东西。 所以它现在有一个更小的元素集来搜索以找到“输入”。

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

根据我的经验,JQuery处理selctors的方式与CSS略有不同。

Josh指出,减少搜索的背景是关键。

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

这如何比较速度?

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

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

善良,

我自己做了一些关于jQuery Selector Performance的研究。 一个很大的问题是Internet Explorer上的classname查找。 IE不支持getElementsByClassName – 因此jQuery和其他框架通过遍历所有DOM元素在JavaScript中“重新实现”它。 查看以下有关jQuery Selector性能的分析博客

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

在其中,作者显示了一个“绑定”jQuery扩展,它显示了评估函数的次数。