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

Ale*_*ldi 6 javascript performance selector microbenchmark

我做了一个很少迭代的测试来测试Document.querySelector和 的效率Element.querySelector

标记:

<form>
  <input type="text" />
</form>
Run Code Online (Sandbox Code Playgroud)

脚本:

查询 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;
Run Code Online (Sandbox Code Playgroud)

查询 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;
Run Code Online (Sandbox Code Playgroud)

日志:

console.log( firstResult ); // 703.7450000001118

console.log( secondResult ); // 1088.3349999999627
Run Code Online (Sandbox Code Playgroud)

日志是惊人的我,因为我认为Element.querySelector只有在节点上查询是元素和后裔Document.querySelector查询当前文档的所有节点上,对不对?

为什么会得到这个结果?

Eva*_*oli 6

根据我上面的评论,选择器考虑了整个文档,然后过滤项目以检查它们是否是目标的后代。所以它很可能仍然需要像document.querySelector需要做的那样扫描整个 DOM 树。

还有就是问题的讨论(仍是当前的行为)这里。您将在下面的代码示例中看到 span 被包含在内,因为它不能只是foo孤立地查询下面的项目。

小提琴

代码:

document.body.innerHTML = '<div><p id="foo"><span></span></p></div>';
var foo = document.getElementById('foo');
alert( foo.querySelectorAll('div span').length);
Run Code Online (Sandbox Code Playgroud)