200

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?

VLAZ
  • 26,331
  • 9
  • 49
  • 67
goesToEleven
  • 2,083
  • 2
  • 12
  • 4
  • 1
    Define better. They're almost entirely different. –  Nov 10 '14 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. – lonesomeday Nov 10 '14 at 16:27
  • If you're asking specifically about the places where they overlap, then it all depends. `qS` and `qSA` may be slower (or maybe not). `qSA` has broader support overall than `gEBCN`. `gEBCN` returns a "live list" and `qSA` does not. –  Nov 10 '14 at 16:29
  • 2
    Oh, and `qS/qSA` can be used from any element context, but `gEBI` can only be used from the `document` context. –  Nov 10 '14 at 16:33
  • 5
    `getElementById` matches the `id` attributes to find DOM nodes, while `querySelector` searches by selectors. So for an invalid selector e.g `
    `, `getElementById('1')` would work while `querySelector('#1')` would fail, unless you tell it to match the `id` attribute (e.g `querySelector('[id="1"]')`.
    – Ismail Dec 22 '18 at 11:06
  • 4
    Just an FYI for anyone reading this, but `querySelector` and `querySelectorAll` are fully supported now. https://caniuse.com/#feat=queryselector – jarrodwhitley Jun 11 '19 at 01:37
  • The `good` thing about `querySelector` is that it returns the first element found. Unlike some of these other methods that return multiple elements. – Martlark May 03 '23 at 01:18

2 Answers2

209

"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).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
51

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".

Thiago Negri
  • 5,221
  • 2
  • 28
  • 39
  • 8
    There are several archived versions: https://web.archive.org/web/20160108040024/http://jsperf.com/getelementbyid-vs-queryselector But the test is actually very old (2010), so the result might be very different with more modern engines. – thomas Aug 05 '16 at 09:38
  • 9
    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 - https://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. – W.Prins Feb 06 '19 at 15:25
  • `nodelist ... is not live` can you provide documentation for that? @W.Prins both methods return the `Element` type. – Maximilian Burszley Dec 30 '19 at 19:06
  • 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. – W.Prins Jan 20 '20 at 22:29
  • This being live in case of GetElementsByClassName is described here: https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#getelementsbyclassname Elsewhere (in https://www.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." – W.Prins Jan 20 '20 at 22:30