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

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(即jQuery嵌入的 Sizzle )引入了“自下而上” ; (要么   “从右到左”的查询方法   DOM。

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

  1. 获取 someTableRow
  2. 内的所有输入元素
  3. 找到每个 input 元素,使用 class =" editMode" 遍历其 span 元素的祖先树。删除没有这些祖先的 input 元素
  4. 找到每个 span.editMode 元素,使用 class =" someColumnClass" 遍历 td 元素的祖先树。删除没有这些祖先的 input 元素
  5. 然而,在您的第一个示例中,您通过每次调用 find()显式限定每个步骤,定义上下文并从那里遍历 down 。您正在执行“自上而下”的操作。做法。它相当于在每一步传递一个上下文,这是通常被视为性能助推器

    $('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 Performance <的分析博客/ A>

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top