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") 快的主要内容,如果未能解决你的问题,请参考以下文章