jQuery 选择器:为啥 $("#id").find("p") 比 $("#id p") 快

Posted

技术标签:

【中文标题】jQuery 选择器:为啥 $("#id").find("p") 比 $("#id p") 快【英文标题】:jQuery selector: Why is $("#id").find("p") faster than $("#id p")jQuery 选择器:为什么 $("#id").find("p") 比 $("#id p") 快 【发布时间】:2012-02-14 08:12:38 【问题描述】:

本页作者:http://24ways.org/2011/your-jquery-now-with-less-suck 断言 jQuery 选择器 $('#id').find('p')$('#id p') 快,尽管如果我理解正确的话,这可能会产生相同的结果。造成这种差异的原因是什么?

【问题讨论】:

【参考方案1】:

因为$('#id').find('p') 被优化为...

document.getElementById('id').getElementsByTagName('p');

...而我猜$('#id p') 将使用querySelectorAll(如果可用),或者基于 javascript 的选择器引擎(如果不可用)。


您应该注意,性能总是因浏览器而异。众所周知,Opera 具有极快的querySelectorAll

另外,不同版本的 jQuery 可能会有不同的优化。

$('#id p') 可能会是(或目前是),因为优化与第一个版本相同。

【讨论】:

我认为querySelectorAll('#id p') 也进行了相当优化。应该测试性能差异,而不是断言。 @Tomalak:我已经对qSA 进行了足够多的测试,知道在大多数浏览器中它的速度确实很慢。这不是一个随意的断言。查看我关于 Opera 的更新。 我并没有说 qSA 总是更快。实际上,我说“我假设”是为了证明我的观点。毕竟,考虑到 jQuery 和浏览器版本之间的巨大差异,以一种或另一种方式支持这样一个通用的陈述是相当困难的。 我没说你这么说。至少那不是我指出我的更新的意图。我的观点是/是我同意你关于qSA 优化的可能性。【参考方案2】:

它是特定于浏览器的,因为 jQuery 在可用时使用querySelectorAll。当我在 WebKit 中进行测试时,它确实更快。事实证明,querySelectorAll 针对这种情况进行了优化。

在 WebKit 中,如果整个选择器是 #<id> 并且文档中只有一个元素具有该 id,则优化为 getElementById。但是,如果选择器是其他任何东西,querySelectorAll 会遍历文档寻找匹配的元素。

是的,应该可以优化这种情况,使它们的性能相同——但现在,没有人这样做。你可以在WebKit源码中找到here,SelectorDataList::execute使用SelectorDataList::canUseIdLookup来决定是否使用getElementById。它看起来像这样:

if (m_selectors.size() != 1)
    return false;
if (m_selectors[0].selector->m_match != CSSSelector::Id)
    return false;
if (!rootNode->inDocument())
    return false;
if (rootNode->document()->inQuirksMode())
    return false;
if (rootNode->document()->containsMultipleElementsWithId(m_selectors[0].selector->value()))
    return false;
return true;

如果您在非 WebKit 浏览器中进行测试,则可能缺少类似的优化。

【讨论】:

以上是关于jQuery 选择器:为啥 $("#id").find("p") 比 $("#id p") 快的主要内容,如果未能解决你的问题,请参考以下文章

为啥html页面里jQuery选择器不起作用

jquery选择器中加变量参数

jquery选择器中加变量参数

jQuery 如何通过 ID 选择器 获取动态ID

jquery选择器$("...")返回的是数组,为啥还能继续练式操作$("...").方法 ?

Jquery--1--选择器分类