10

I did a test with few iterations to test efficiency of Document.querySelector and Element.querySelector.

Markup:

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

Script:

Querying with 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;

Querying with 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;

Log:

console.log( firstResult ); // 703.7450000001118

console.log( secondResult ); // 1088.3349999999627

The log is amazing for me because i think that Element.querySelector query only on nodes that is a descendant of the element and Document.querySelector query on all nodes of current document, right?

Why get this result?

Alexandre Thebaldi
  • 4,546
  • 6
  • 41
  • 55
  • If you add a 1000 sibling nodes to the form, you will probably see the performance of the document level search drop. – Jonas Høgh Sep 07 '15 at 04:10
  • 2
    The test [here](http://jsperf.com/document-vs-element-queryselectorall-performance/3), shows that your statement is incorrect – Tushar Sep 07 '15 at 04:11
  • I don't know the answer to your question, or whether yours is a good benchmark, but a difference of 300 microseconds per call hardly seems like something worth worrying about in real life. –  Sep 07 '15 at 04:13
  • It's likely due to this: http://lists.w3.org/Archives/Public/public-webapi/2008Apr/0251.html The selector takes into account the entire document, then filters the list to see if the node is a descendant of the element. – Evan Trimboli Sep 07 '15 at 04:15
  • I'm voting to close this question as off-topic because it belongs to http://codereview.stackexchange.com/ – Shiva Sep 07 '15 at 04:17
  • @Shiva Why do you think this is a code review question? –  Sep 07 '15 at 04:21
  • @torazaburo See http://codereview.stackexchange.com/tour and search for "Ask about..." . Don't you see "Performance" listed in there? – Shiva Sep 07 '15 at 04:25
  • 6
    yes, but this question is not asking for a Code Review, or asking for a performance tune-up. It's asking **why** one method is significantly faster than another, which is definitely the purview of SO. – Kaz Sep 07 '15 at 04:25
  • @Shiva, that means, "My programs run slow and I don't know why and please review my code and suggest how to make it faster". That's different from a question about API performance. –  Sep 07 '15 at 04:26
  • Questions asking for an explanation of code (which this is) are off topic on Code Review. – Phrancis Sep 07 '15 at 04:27
  • every browser I've tried is ~10 to 20 times faster on secondResult - so, what browser gives that result? Mosaic 2.0? – Jaromanda X Sep 07 '15 at 04:29
  • @JaromandaX Google Chrome 46.0.2490.13 beta-m (64-bit) – Alexandre Thebaldi Sep 07 '15 at 04:31
  • In a real simple test in Chrome for me the second form was about 2x faster. –  Sep 07 '15 at 05:14
  • @Zak Performance is not listed anywhere on SO FAQ / Tour, whereas it is, on codereview.stackexchange, so how are you saying "definitely the purview of SO"? Still not convinced. Show me how this fits into SO. – Shiva Sep 07 '15 at 06:30
  • 2
    BEcause they're not asking for performance help as such, they're saying "Function A is faster than Function B, why?". Which is all about how those functions actually work. Which is a SO-type question. I can tell you right now, this question would be immediately closed as off-topic on Code Review. We don't do code explanations. – Kaz Sep 07 '15 at 06:34

2 Answers2

6

From my comment above, the selector takes into account the entire document, then filters the items to check if they are descendants of the target. So it's likely that it still needs to scan the entire DOM tree like document.querySelector would need to do.

There is a discussion of the issue (that is still the current behaviour) here. You'll see in the code sample below the span is included as a result, because it can't just query items below foo in isolation.

Fiddle

Code:

document.body.innerHTML = '<div><p id="foo"><span></span></p></div>';
var foo = document.getElementById('foo');
alert( foo.querySelectorAll('div span').length);
Evan Trimboli
  • 29,900
  • 6
  • 45
  • 66
0

It seems obvious to me that the result should be null, as the context is outside the element the search is began from.

Things are simple when you make them simple.... Don't you are fixing the "context", how can you think the "context" is "outside" the "context" you stated... In the example from Evan is really curious to get any result, as there are no "div" in the foo node where the selector is executed... but the answer is "I've found a span descendant of a div... but you'll not find the div there"

Cesc
  • 21
  • 1