5 Tips for More Efficient jQuery Selectors

Tweet

As the name implies, jQuery focuses on queries. The core of the library allows you to find DOM elements using CSS selector syntax and run methods on that collection.

jQuery uses native browser API methods to retrieve DOM collections. Newer browsers support getElementsByClassName, querySelector and querySelectorAll which parses CSS syntax. However, older browsers only offer getElementById and getElementByTagName. In the worst scenarios, jQuery’s Sizzle engine must parse the selector string and hunt for matching elements.

Here are five tips which could help you optimize your jQuery selectors…

1. Use an ID if Possible

HTML ID attributes are unique in every page and even older browsers can locate a single element very quickly:


$("#myelement");

2. Avoid Selecting by Class Only

The following class selector will run quickly in modern browsers:


$(".myclass");

Unfortunately, in older browser such as IE6/7 and Firefox 2, jQuery must examine every element on the page to determine whether “myclass” has been applied.

The selector will be more efficient if we qualify it with a tag name, e.g.


$("div.myclass");

jQuery can now restrict the search to DIV elements only.

3. Keep it Simple!

Avoid overly complex selectors. Unless you have an incredibly complex HTML document, it’s rare you’ll need any more than two or three qualifiers.

Consider the following complex selector:


$("body #page:first-child article.main p#intro em");

p#intro must be unique so the selector can be simplified:


$("p#intro em");

4. Increase Specificity from Left to Right

A little knowledge of jQuery’s selector engine is useful. It works from the last selector first so, in older browsers, a query such as:


$("p#intro em");

loads every em element into an array. It then works up the parents of each node and rejects those where p#intro cannot be found. The query will be particularly inefficient if you have hundreds of em tags on the page.

Depending on your document, the query can be optimized by retrieving the best-qualified selector first. It can then be used as a starting point for child selectors, e.g.


$("em", $("p#intro")); // or
$("p#intro").find("em");

5. Avoid Selector Repetition

It’s rarely necessary to use the same selector twice. The following code selects every p tag three times:


$("p").css("color", "blue");
$("p").css("font-size", "1.2em");
$("p").text("Text changed!");

Remember jQuery offers chaining; multiple methods can be applied to the same collection. Therefore, the same code can be re-written so it applies to a single selector:


$("p").css({ "color": "blue", "font-size": "1.2em"}).text("Text changed!");

You should cache the jQuery object in a variable if you need to use the same set of elements multiple times, e.g.


var $p = $("p");
$p.css("color", "blue");
$p.text("Text changed!");

Unlike standard DOM collections, jQuery collections aren’t live and the object is not updated when paragraph tags are added or removed from the document. You can code around this restriction by creating a DOM collection and passing it to the jQuery function when it’s required, e.g.


var p = document.getElementByTagName("p");
$(p).css("color", "blue");
// update the DOM
$(p).text("Text changed!");

Do you have any further jQuery selector optimization tips?

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://uranbold.com Uranbold

    Really useful info. THank you!

  • http://abhishek.dilliwal.com abhishek dilliwal

    Nice one… i was not knowing about the left to right one!

  • http://twitter.com/jokeyrhyme Ron Waldon

    Use direct-descendant operators whenever possible, or use jQuery.fn.children instead of jQuery.fn.find.

    For example, these:
    $(‘body > h1′)
    $(‘body’).children(‘h1′)
    are way faster than these:
    $(‘body h1′)
    $(‘body’).find(‘h1′)

    Ask yourself, do you really want to be traversing the entire DOM structure to find what you want? Or can you plan in advance? Do you know exactly where to look?

    • http://gregpettit.ca Greg

      Have you verified this? A quick jsPerf shows that it may not be true. I say ‘may not’ because after all jsPerf is just one way of testing performance. But, based on that test, .find() is significantly faster than .children(). (the former being 99% slower!) Presumably because it still has to recurse the DOM and then verify that they’re children of the first selector.

  • http://willmorgan.co.uk Will Morgan

    Actually, specifying p#Intro is slower than simply #Intro. This is because the selector engine has to check that the element is a paragraph tag.

    That aside, you should be using classes if you wish to identify groups of different kinds of elements. Different IDs on different tags on different pages makes for bad design and lots of confusion for other developers.

  • soninke
  • http://www.howtomake.com.ua HTM

    good for junior!

  • http://www.vancelucas.com Vance Lucas

    On #3, the selector should be simplified to just:
    $(“#intro em”);

    That way jQuery can just use getElementById internally without an additional element type check (for the “p” tag), which is the fastest selector by far.

    • Boris Delormas

      #1 should be simplified to

      document.getElementById(‘myelement’)

      since native selectors are still best performing

      • http://gregpettit.ca Greg

        Well…. you’re creating a jQuery object, not just getting the element. If pure performance in selection and getting certain attributes natively (this.id) is all that matters then yes. But presumably people use jQuery because they like it as an abstraction and utility layer. For example, you can chain multiple functions after creating the jQuery object, which is useful syntax to have. The base assumption is “for whatever reason, I’m using jQuery,” and the problem to solve is “how can I do that more efficiently?”

        If your question is, “How do I peel an orange?” and somebody answers, “just peel a banana; you can finish much faster,” the question isn’t really answered.

  • http://coderbay.com coderbay

    very good tips.