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

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

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

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

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


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

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

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

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

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

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