216

I have heard that querySelector and querySelectorAll are new methods to select DOM elements. How do they compare to the older methods, getElementById and getElementsByClassName in terms of performance and browser support?

How does the performance compare to using jQuery's query selector?

What is the difference between querySelector and getElementById? When should we use querySelector instead of getElementById? Is there any example which is not possible using getElementById?

7
  • 1
    Define better. They're almost entirely different. Commented Nov 10, 2014 at 16:27
  • 5
    This is like asking "is a single-size spanner better than an adjustable spanner?" The answer is: they are more powerful and more flexible, and so on many occasions superior, but getElementById and getElementsByClassName are still ideal for the purposes their names describe. Commented Nov 10, 2014 at 16:27
  • 2
    Oh, and qS/qSA can be used from any element context, but gEBI can only be used from the document context. Commented Nov 10, 2014 at 16:33
  • 6
    getElementById matches the id attributes to find DOM nodes, while querySelector searches by selectors. So for an invalid selector e.g <div id="1"></div>, getElementById('1') would work while querySelector('#1') would fail, unless you tell it to match the id attribute (e.g querySelector('[id="1"]'). Commented Dec 22, 2018 at 11:06
  • 4
    Just an FYI for anyone reading this, but querySelector and querySelectorAll are fully supported now. caniuse.com/#feat=queryselector Commented Jun 11, 2019 at 1:37

2 Answers 2

224

"Better" is subjective.

querySelector is the newer feature.

getElementById is better supported than querySelector (not that it matters today, some years after this answer was originally written).

querySelectorAll is better supported than getElementsByClassName but querySelectorAll gives you a static node list while getElementsByClassName gives you a live node list.

querySelector lets you find elements with rules that can't be expressed with getElementById and getElementsByClassName

You need to pick the appropriate tool for any given task.

(In the above, for querySelector read querySelector / querySelectorAll).

Sign up to request clarification or add additional context in comments.

2 Comments

querySelector support: caniuse.com/#feat=queryselector
Very good answer and here are some benchmark tests
55

The functions getElementById and getElementsByClassName are very specific, while querySelector and querySelectorAll are more elaborate. My guess is that they will actually have a worse performance.

Also, you need to check for the support of each function in the browsers you are targetting. The newer it is, the higher probability of lack of support or the function being "buggy".

5 Comments

There are several archived versions: web.archive.org/web/20160108040024/http://jsperf.com/… But the test is actually very old (2010), so the result might be very different with more modern engines.
The archived page actually is dynamic and allows you to re-run the test on your current browser. querySelectorAll is still slower by reportedly about 37% on my browser. (Chrome 71 - vgy.me/TwGL3o.png) It's also worth noting that getElementById returns a live result, meaning that if you change the DOM , the change will be reflected by the result obtained by getElementByID (if in scope) whereas the nodelist returned by querySelectorAll is a snapshot, e.g. as things were at the time the call was made, the result will not reflect subsequent changes to the DOM.
nodelist ... is not live can you provide documentation for that? @W.Prins both methods return the Element type.
Ah, I see I made a typo, please accept my apologies! I should have written "getElementsByClassName" where I wrote "getElementByID", e.g. it is getElementsByClassName (and similar) which returns a live resultset". Indeed both getElementsByClassName and querySelectorAll returns a NodeList, but in the former case it's live, and in the latter it's a snapshot.
This being live in case of GetElementsByClassName is described here: w3.org/TR/2008/WD-html5-20080610/… Elsewhere (in w3.org/TR/selectors-api/#queryselectorall) it is written: "The NodeList object returned by the querySelectorAll() method must be static, not live ([DOM-LEVEL-3-CORE], section 1.1.1). Subsequent changes to the structure of the underlying document must not be reflected in the NodeList object."

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.