jQuery选择器:为什么$(“#id”)。find(“p”)比$(“#id p”)快

时间:2012-01-19 16:50:19

标签: javascript jquery performance jquery-selectors

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

2 个答案:

答案 0 :(得分:6)

因为$('#id').find('p')已经过优化,可以...

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

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


您应该注意,浏览器之间的性能始终存在差异。众所周知,Opera的速度非常快querySelectorAll

此外,不同版本的jQuery可能会提出不同的优化。

可能$('#id p')(或当前是)给出与第一个版本相同的优化。

答案 1 :(得分:2)

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

在WebKit中,如果整个选择器都是#<id>并且文档中只有一个带有该ID的元素,则优化为getElementById。但是,如果选择器是其他任何内容,querySelectorAll遍历文档以查找匹配的元素。

是的,应该可以优化这种情况,以便它们执行相同的操作 - 但是现在,没有人拥有。您可以在WebKit源代码中找到它hereSelectorDataList::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浏览器中进行测试,则可能缺少类似的优化。