jQuery 选择器性能 [英] jQuery selector performance
问题描述
根据我如何表达我的选择器,我的性能会有很大差异.例如,看看这 2 个选择器,它们选择完全相同的元素:
I'm having huge variations in performance depending on how I express my selectors. For example, look at these 2 selectors, which select exactly the same elements:
A) someTableRow.find("td.someColumnClass").find("span.editMode").find("input")
B) someTableRow.find("td.someColumnClass span.editMode input")
我希望 B) 更快,因为只有 1 个调用,但实际上我发现 A) 的执行速度快了大约 8 倍.我不知道为什么,有人有任何见解吗?谢谢
I would expect to B) to be faster as there is only 1 call, but in fact I'm finding A) executes around 8 times faster. I have no idea why, anyone have any insight? Thanks
推荐答案
假设您至少使用 jQuery 1.3(即添加了 Sizzle),您看到的性能是由于遍历 DOM 的变化.从 这里:
Presuming you are using at least jQuery 1.3 (i.e. with the addition of Sizzle), the performance you are seeing is due to the change in which the DOM is traversed. From here:
直到并包括 jQuery 1.2.6选择器引擎以自上而下"的方式工作(或从左到右")方式.jQuery1.3.x(即 jQuery 嵌入的 Sizzle)引入了自下而上"(或者"从右到左") 查询方法DOM.
Up to and including jQuery 1.2.6 the selector engine worked in a "top down" (or "left to right") manner. jQuery 1.3.x (ie, Sizzle, which jQuery embeds) introduced a "bottom up" (or "right to left") approach to querying the DOM.
在您的第二个示例("td.someColumnClass span.editMode input"
)中,Sizzle 有效地做到了这一点:
In your second example ("td.someColumnClass span.editMode input"
), Sizzle effectively does this:
- 获取
someTableRow
内的所有 - 对于找到的每个
input
元素,使用class="editMode"
遍历其祖先树以查找span
元素.删除没有这些祖先的input
元素 - 对于找到的每个
span.editMode
元素,遍历其祖先树以查找具有class="someColumnClass"
的td
元素.删除没有这些祖先的input
元素
input
元素- get all
input
elements insidesomeTableRow
- for each
input
element found, traverse its ancestor tree forspan
elements withclass="editMode"
. Removeinput
elements that don't have these ancestors - for each
span.editMode
element found, traverse its ancestor tree fortd
elements withclass="someColumnClass"
. Removeinput
elements that don't have these ancestors
然而,在您的第一个示例中,您通过每次调用 find()
来明确限定每个步骤,定义上下文并从那里遍历 down.您正在执行自上而下"的方法.相当于每一步都传入一个上下文,即通常被认为是性能提升器:
In your first example however, your are qualifying each step explicitly with each call to find()
, defining a context and traversing down from there. You are enforcing the "top-down" approach. It is equivalent to passing in a context at each step, which is generally considered a performance booster:
$('input', $('span.editMode', $('td.someColumnClass', someTableRow)))
这篇关于jQuery 选择器性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!