【发布时间】:2012-02-14 08:12:38
【问题描述】:
本页作者:http://24ways.org/2011/your-jquery-now-with-less-suck 断言 jQuery 选择器
$('#id').find('p') 比 $('#id p') 快,尽管如果我理解正确的话,这可能会产生相同的结果。造成这种差异的原因是什么?
【问题讨论】:
标签: javascript jquery performance jquery-selectors
本页作者:http://24ways.org/2011/your-jquery-now-with-less-suck 断言 jQuery 选择器
$('#id').find('p') 比 $('#id p') 快,尽管如果我理解正确的话,这可能会产生相同的结果。造成这种差异的原因是什么?
【问题讨论】:
标签: javascript jquery performance jquery-selectors
因为$('#id').find('p') 被优化为...
document.getElementById('id').getElementsByTagName('p');
...而我猜$('#id p') 将使用querySelectorAll(如果可用),或者基于 JavaScript 的选择器引擎(如果不可用)。
您应该注意,性能总是因浏览器而异。众所周知,Opera 具有极快的querySelectorAll。
另外,不同版本的 jQuery 可能会有不同的优化。
$('#id p') 可能会是(或目前是),因为优化与第一个版本相同。
【讨论】:
querySelectorAll('#id p') 也进行了相当优化。应该测试性能差异,而不是断言。
qSA 进行了足够多的测试,知道在大多数浏览器中它的速度确实很慢。这不是一个随意的断言。查看我关于 Opera 的更新。
qSA 优化的可能性。
它是特定于浏览器的,因为 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 浏览器中进行测试,则可能缺少类似的优化。
【讨论】: