Quick Tip – Optimizing DOM Traversal
The topic of optimization has come up a number of times in the jQuery mailing list. jQuery's DOM traversal is powerful and easy, but it can sometimes be slow as well. As with any JavaScript library or framework, the helper methods will be slower than the plain old JavaScript (p.o.j) methods. Nevertheless, if we keep in mind the jQuery's speed hierarchy, the speed difference between jQuery and p.o.j. will often be negligible.
The "speed hierarchy" goes like this, in order of fastest to slowest:
- ID : $('#some-id')
- Element : $('div')
- Class : $('.some-class')
jQuery uses JavaScript's native getElementById()
to find an ID in the document. It's fast — probably the single fastest way to find something in the DOM — because it's only looking for a single unique thing, and it'll stop looking once it has found it. So, if we have <h2 id="title">This is my title</h2>
, we would use $('#title')
, not $('h2#title')
to access it.
To find a bare class name, as in #3 above, jQuery goes through every element in the entire DOM. To find an element, on the other hand, it uses getElementsByTagName()
, thereby limiting the number of elements it has to traverse right from the start. Therefore, if we know which element the class is tied to, we can speed up the traversal significantly by referring to it, using, for example, $('div.some-class')
rather than $('.some-class')
.
Likewise, we can help jQuery gather our classes faster if we can limit where jQuery looks to a particular ID: $('#sidebar .menu')
, not $('.menu')
.
I'm sure there other ways to make DOM traversal speedier, so if anyone knows any other tricks, I'd love to see them in the comments. Also, I should probably reiterate that if speed is all you care about, no library/framework is going to beat p.o.j.
Update: Motivated by enej's comment, I put together a little speed-test page where you can try out a number of different DOM queries and see how fast they are. Since I posted a link to the page on the jQuery mailing list, there has been quite a bit of activity in this area. Aaron Heimlich extended the speed test to work in conjunction with Firebug for some awesome reporting, and rumor has it that Yehuda Katz is working on an entire speed-test suite.
Update
Please be aware that these optimizations are not necessarily helpful as of jQuery 1.3 because of the new "Sizzle" selector engine.