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 ?
If you run this code you will find that querySelector is slower than getElementById and getElementByClassName. Among getElementbyId and getElementByClassName, getElementById is slightly faster.
As expected accessing an element from querySelectorAll is much faster - accessing an element from getElementsByTagName and getElementsByClassName is nearly 100 times slower!
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.
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.
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.
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".
Then I ran four tests.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With