Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance of getElementById vs. getElementsByClassName vs. querySelector

I was reading about dom manipulation topic in dev.mozilla and I came across with a statement that suggest us to use querySelector for element selection:

Note that, as with many things in JavaScript, there are many ways to select an element and store a reference to it in a variable. Document.querySelector() is the recommended modern approach...

However, when I made a test I realized getElementsByClassName() is by far the best method for element selection. How come it can be faster than getElementById() ? And why mozilla dev guide still recomends using querySelector() even though it's the slowest one amongs them ?

like image 217
brainoverflow98 Avatar asked Jul 23 '19 07:07

brainoverflow98


People also ask

Is querySelector faster than getElementById?

If you run this code you will find that querySelector is slower than getElementById and getElementByClassName. Among getElementbyId and getElementByClassName, getElementById is slightly faster.

Is getElementsByClassName faster than querySelector?

As expected accessing an element from querySelectorAll is much faster - accessing an element from getElementsByTagName and getElementsByClassName is nearly 100 times slower!

Is querySelector better than getElementById?

getElementById is better supported than querySelector . querySelector is better supported than getElementsByClassName but querySelector gives you a static node list while getElementsByClassName gives you a live node list. You need to pick the appropriate tool for any given task.

Is querySelector better than getElementsByClassName?

If you only need to select an element by ID or class, you can use getElementById or getElementsByClassName, respectively. If you need to use a more elaborate rule to select elements, the querySelector method is your best option. Both querySelector and getElementById have been part of JavaScript for a while.


1 Answers

The main advantage of document.querySelector is the ease of use with more complex CSS queries.

const loginFields = document.querySelector("form.login input");
if (loginFields.some((field) => field.value.trim() === "") {
    alert("Please fill in all fields");
}

The alternative would be to use document.getElementsByClassName and Element.getElementsByTagName.

const loginFields = document.getElementsByClassName(".login")[0]
    .getElementsByTagName("input");
if (loginFields.some((field) => field.value.trim() === "") {
    alert("Please fill in all fields");
}

As you may have noticed, you'll often store the return result into a constant/variable. You're (usually) not supposed to call this in a for/while loop.


Regarding the (archived) performance test, it looks quite unfair because all tests except the class test will run two queries.

JSPerf test


So I decided to do some more testing. In the HTML of that page, I added the id "codeOne" to the first element with the class "code".

HTML code

Then I ran four tests.

JavaScript test results

Out of these test results, I can conclude that getElementById using id (691ms) is the clear winner with querySelector using id (749ms) coming in second. This is because ids are easy to look up as browsers copied this feature from Internet Explorer, which was the most dominant browser in the past. You can even use ids as if they are variables.

Javascript test with id variable

Please don't do that because it's less readable. It's also not faster.

When we take a look at the tests using class, we can see a massive performance difference between getElementsByClassName (778ms) and querySelector (1460ms). This is because the former will only look for classNames while the latter will do some extra checks because it can use a complex query like '#id.class[attr="value"]' or "form > input".


The final conclusion is that you can use document.querySelector for one element and document.querySelectorAll for multiple elements just for simplicity as any CSS query will work. The functions getElementById and getElementsByClassName (as well as getElementsByTagName, not included) should always be faster in theory but in practice this shouldn't affect the performance of your website. You (probably) won't call these functions in a loop so you can just store the result in a variable.

like image 144
User Avatar answered Sep 24 '22 03:09

User