为什么Document.querySelector比Element.querySelector更高效

10

我进行了一些迭代测试,以测试 Document.querySelectorElement.querySelector 的效率。

标记:

<form>
  <input type="text" />
</form>

脚本:

使用 Document.querySelector 查询

begin = performance.now();

var 
  i = 0,
  iterations = 999999;

for ( i; i < iterations; i++ ) 
{
 element = document.querySelector('[type="text"]');
}

end = performance.now();

firstResult = end - begin;

使用 Element.querySelector 进行查询

begin = performance.now();

var 
  i = 0,
  iterations = 999999,
  form = document.querySelector('form');

for ( i; i < iterations; i++ ) 
{
 element = form.querySelector('[type="text"]');
}

end = performance.now();

secondResult = end - begin;

日志:

console.log( firstResult ); // 703.7450000001118

console.log( secondResult ); // 1088.3349999999627

对我来说,日志是很棒的,因为我认为Element.querySelector仅在该元素的后代节点中查询,而Document.querySelector查询当前文档的所有节点,对吗?

为什么会得到这个结果呢?


2
这个测试链接表明你的说法是不正确的。 - Tushar
很可能是由于这个原因:http://lists.w3.org/Archives/Public/public-webapi/2008Apr/0251.html该选择器考虑了整个文档,然后过滤列表以查看节点是否是元素的后代。 - Evan Trimboli
我投票关闭此问题,因为它属于http://codereview.stackexchange.com/。 - Shiva
6
是的,但这个问题并不是要求代码审查,也不是要求性能调优。它询问为什么一种方法比另一种方法明显更快,这绝对是SO的范畴。 - Kaz
2
因为他们并不是在寻求性能方面的帮助,而是在问“函数A比函数B快,为什么?”这完全取决于这些函数的实际工作方式,这是一个类似于SO的问题。我可以告诉你,这个问题会被立即关闭,因为它不符合Code Review的主题。我们不提供代码解释。 - Kaz
显示剩余10条评论
2个回答

6
从我上面的评论中可以看出,选择器考虑整个文档,然后过滤项目以检查它们是否是目标的子孙。因此,它可能仍然需要像document.querySelector一样扫描整个DOM树。
这个问题有一个讨论(仍然是当前行为),在这里。在下面的代码示例中,您将看到span被包含在结果中,因为它不能只查询foo以下的项目。 Fiddle 代码:
document.body.innerHTML = '<div><p id="foo"><span></span></p></div>';
var foo = document.getElementById('foo');
alert( foo.querySelectorAll('div span').length);

0

我认为很明显结果应该是 null,因为搜索的上下文在元素之外。

当你把事情简单化时,一切都变得简单了... 如果你没有修复“上下文”,那你怎么能认为“上下文”是“外部”的呢... 在 Evan 的示例中,得到任何结果都很奇怪,因为在执行选择器的 foo 节点中没有“div”... 但答案是“我找到了一个 div 的后代 span... 但你不会在那里找到 div”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接