最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Performance between doc.querySelectorAll('#id element') vs doc.querySelector('#id')

programmeradmin4浏览0评论

I'm trying to find an element with:

doc.querySelectorAll('#divContentList article');

It work well, but another developer told me I should write:

doc.querySelector('#divContentList').querySelectorAll('article');

He said this is better because it go direct to #divContentList and then look for article elements.

I don't think his solution is the best in speed performance and it search the element twice. I thought querySelectorAll is awesome enough to do its job.

Main question is, which line of code is the best overall?

I'm trying to find an element with:

doc.querySelectorAll('#divContentList article');

It work well, but another developer told me I should write:

doc.querySelector('#divContentList').querySelectorAll('article');

He said this is better because it go direct to #divContentList and then look for article elements.

I don't think his solution is the best in speed performance and it search the element twice. I thought querySelectorAll is awesome enough to do its job.

Main question is, which line of code is the best overall?

Share Improve this question edited Feb 10, 2015 at 13:22 BoltClock 725k165 gold badges1.4k silver badges1.4k bronze badges asked Feb 10, 2015 at 13:21 Harianto van InsulindeHarianto van Insulinde 611 silver badge6 bronze badges 4
  • 2 Has either of you tested the code? – BoltClock Commented Feb 10, 2015 at 13:22
  • You should definitely test it, but doc.querySelector('#divContentList') will definitely will be slower than #getElementById(). – meskobalazs Commented Feb 10, 2015 at 13:25
  • 1 This almost certainly isn't the slowest thing in your application. Don't worry about it. – joews Commented Feb 10, 2015 at 13:25
  • 1 For what it's worth, I would use getElementById if possible. See this test case: jsperf./selector-tests-jm – Joseph Marikle Commented Feb 10, 2015 at 13:31
Add a ment  | 

5 Answers 5

Reset to default 4

Thanks to Mauricio Soares with his jsPerf first example:

<div id="divContentList">
    <article></article>
</div>

Would indeed the first method:
doc.querySelectorAll('#divContentList article');
faster if there is only ONE article in it.

I have modified jsPerf from to 10, then to 1000 article’s, the performance differences are dramatic. Check it here

<div id="divContentList">
    <article></article>
    ...
    <article></article>
</div>

This will result that second method on my question:
doc.querySelector('#divContentList').querySelectorAll('article');
is much faster

And last, the one by using getElementById the performance increases slightly more.
doc.getElementById('divContentList').querySelectorAll('article');
That the best performance

Keith Rousseau got right that querySelectorAll evaluates from right to left.

Edit:

Also I found out something different about querySelector and getElementById/getElementsByTagName. querySelector returns Static NodeList, while getElementById returns Live NodeList.

I made another test
document.getElementById('divContentList').getElementsByTagName('article');
This one takes the cake. The difference is ridiculous

The answer to this question is either:

  • Method 1 is faster
  • Method 2 is faster
  • There is no difference

The issue is that the answer might change over time. Browser vendors tend to optimize methods that are used a lot. If method 1 is used a lot it will likely be faster, or be faster in the future.

Both methods seem equal to me (with the given input). If there is a fundamental underlying reason why one should be faster: use the faster method.


Since your first match is an id there can always only be one match.

If your query was ".parent .child" and there are many parents that have no children then ".parent .child" would probably be faster than (".parent").qsa(".child").

querySelectorAll evaluates from right to left so the first one will find all articles on the page and then filter that down to just those underneath divContentList. I would do getElementById for the id and then find the articles underneath.

But as others have said, test it. And test it in multiple browsers.

You could use jsPerf for this kind of tests...

I've set up a simple performance test with your use case here, and it seems that they have a similar performance, the "single" querySelector seems to be a little bit more performatic some times, but I don't think this is gonna be a problem at all in your application.

Granted, this is an old question, but stumbled across this & felt like weighing in. One big note ahead of time, which I don't think anyone else delved into, is: those two statements aren't technically synonymous. This may explain the general performance difference.

The easiest example of this is actually YouTube. If you go to any video, you'll find that they actually repeat the ID, #content. In the first video I tried, after loading the ments section, document.querySelectorAll("#content") actually returned about 20 elements. This is not to standard, and the W3's HTML Validator will actually tell you this is invalid HTML. However, browsers still permit this, rather than straight-up rejecting or modifying the HTML.

If your site had repeated usages of #divContentList, your statement would return all of the article elements from within all of them; whereas your coworker's would only return articles nested within the the first instance of #divContentList that it found. This may explain why your coworkers appears to generally be faster (see below). And like most people've already pointed out, replacing his/her first querySelector with getElementById would likely be even faster across all browsers.


Beyond that, I agree with the general idea that, "if you want to know the performance of something: just measure it." but be careful with how you construct your tests. Here's an example where the JS engine optimized out the actual test case. My advice is always test within the context of your actual use-case. There have been threads talking about how element.querySelector can actually be slower than document.querySelector; however, from brief recent testing, I could not replicate this.

Using IDs / classes like #sidebar and .question-hyperlink on this page itself, in all cases document.querySelector('<ID>').querySelectorAll('<CLASS>'); outperformed document.querySelectorAll('<ID> <CLASS>');.

However, and I feel like this is critical, the difference was never more than ~10-20%. At a certain point the question bees, "is the trade-off between readability / writeability vs performance worthwhile". If you're only running this statement one or two times, the difference is likely in the order of microseconds. For a general use-case, either your original statement or your coworker's would be fine.

And one final note,

I don't think his solution is the best in speed performance and it search the element twice

If you felt like a bit of reading, you could look into how browsers actually implement these lookup methods for webpages. Looking at the Firefox source, what you'll find is "getElementById" uses a hashtable lookup, which makes it nearly instantaneous to find a result. The implementation will vary between vendors, which is why it can be important that you test your site on many different browsers.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论