Posterous theme by Cory Watilo

Optimizing jQuery Selector Performance

Despite the fact that the capacity of modern JavaScript engines is expanding rapidly, I found myself recently fighting with JS performance on a very large web page.  This was an ASP.NET application with one very complex page, very large DOM tree, lots of elements and lots of JS interactions.

As the page became larger and more data was pumped into the DOM the time it took to locate an element or set of elements in the DOM began to lengthen.  My attempts to locate any solid information in Google on improving this situation was fruitless.  So, I starting digging through the jQuery source code to see how the selector engine worked...this was also useless.  Clearly the skills of the JS Ninjas that created jQuery are far superior to mine.

So, then it just became a thought experiment.  Knowing that jQuery uses a context sensitive combination of XPath, native browser API's, and some fancy string parsing for CSS3 selectors there are a few optimizations that come to mind.

Qualify your selector strings when searching by class.
Because one way that jQuery can find DOM elements is XPath style searching, it's important to qualify your selector strings.  Turning $(".some-class") into $("div.container > div.head > div.some-class") can really make a difference.  This is especially true when the branches of your DOM tree become very deep.

Don't Qualify your selector when searching by id.
Because searching by id uses the browsers native getElementById method (which is very fast) it doesn't make sense to overly qualify a selector string that's looking for a unique element.  So $("div#someid") is actually slower than $("#someid").

Select By Element(s)
Don't forget that your argument to $() can also be a reference to an element directly.  One of the techniques that I've used to get over huge numbers of DOM elements is to do some pre-caching of element objects before doing any manipulation.  For example I might keep an array in JavaScript of all of the elements of a particular group.  

Say you have a bunch of textboxes on a page and they're scattered all around in deeply nested trees.  Half of the textboxes belong to group A and the other group B.  I might set up two JavaScript arrays (elementsAarray, and elementsBarray) and before the page is rendered I'll go and grab all of those elements and plop them into my arrays.  This way I can simply grab that array of elements in group A with $(elementsAarray) which completely cuts out the need for DOM traversal.

- - - - -

There are likely other ways to tweak your selectors and I'd love to hear how other people have tackled this issue.  Here's hoping that JavaScript engines get so fast that we don't have to care!

| Viewed
times | Favorited 0 times
Filed under:  

1 Comment

Nov 16, 2008
redsquare said...
Cache frequently used selectors. One perf improvement is to put the selector into a var.
Dont use $(this) throughout a function.
At the top say var $this=$(this) then refer to the var.

Leave a comment...