The current project I’ve been working on, heavily relies on jQuery and Highcharts/Highstock libraries, I must confess that at the beginning of the project my skills in the client-side were more than rusted, so, I began reading a lot of articles about new techniques and good practices to catch up very quickly, in the meantime, I start taking some notes about “best practices”1 that promotes a better use of jQuery2, I hope you find this information useful, if you have more tips or any doubt please leave your comments at the end of this article.
The first recommendation is to use the last version of jQuery, the reason is that in new releases you will find new features, and also a good amount of bugs and performance problems are fixed.
One of the benefits to work with jQuery is that it lets you find elements inside of the DOM using a syntax similar to the CSS selectors3. But, please, take into account the following considerations.
Modern browser support
querySelectorAll directives. However, old browser versions only offer support
getElementByTagName directives. So, if you are only
targeting recent version of browsers, you might not need anything more than what
the browser offers.
One of the first tips that you need to know is this: Have preference over IDs
whenever it’s possible, even in old browser versions the search based on the ID
of an element is fast because the jQuery selector internally is converted to the
Avoid the tag prefix when you search for an
The example above creates an inefficient query because in the first place we
traverse all the
div tags in the document, after that we look up the
In the same way, it’s redundant to nest multiple IDs in a jQuery selector:
In this case always use the most specific
Also, if you want to select multiple elements, this implies that you need to
traverse all the DOM, which can generate a hit in your query performance, so,
you can avoid this negative impact descending from the most near ID element, for
example, imagine that you need to capture all the
input elements inside of a
#myform (yes, I know, this ID name sucks, remember, it’s
just for example purposes)
Avoid the selection of elements only by class
Avoid to select an element only by its class, the major hit in performance
occurs when your browser doesn’t support the native call
getElementByClassName, in old versions (like IE 6/7/8 and Mozilla Firefox 2)
jQuery needs to examine each element in the page to determine where is the class
that we are looking for.
One workaround that you can use is to prefix the search with the tag element associated with the class “myclass”.
But if you are targeting only modern browsers, you better try
Whenever you need to use multiple times the object returned by a jQuery selector, please store that object in a variable, avoid the following practice:
In this case you are making three queries to get the same object!, you can improve the example above as follows:
In the example above we store the object (cache) returned by the jQuery selector, after that we apply multiple methods over the same object.
Another advantage of storing objects in cache memory is that you can make sub- queries, just look at the following example:
And now we apply some queries over the unordered list:
After that we make some sub-queries:
The principal benefit of store jQuery objects in memory is that the subsequent queries don’t need to traverse again the DOM.
See: jQuery Cached Set
Look at the following example:
Most of the jQuery methods returns an object, that feature facilitate the method chaining over the same element:
See: jQuery chaining
Group the set of parameters over the same method
You can rearrange the previous example as this:
This way you can reduce the number of times that you need to call the same methods over the same objects. This technique create a unique literal object that combines the set of parameters that we’ll use to pass information to the method.
Minimize the use of .append(), .insertBefore() and .insertAfter()
If you want to use the
.append() method, try to avoid its use inside a loop,
in the first place you can try to generate HTML strings in memory, after your
cycle ends you can append your new string to the content instead of apply the
.append() method inside your cycle.
Considering the following HTML structure:
Please, avoid the following pattern:
One approach can be this:
Also, you can replace the
.append() method with
.replaceWith() in some cases:
Take this HTML structure as an example:
One way to manage the navigation buttons are this:
This is really terrible because you bound an event to multiple DOM elements.
You can mitigate the example above as this:
In the example above we use event delegation, this means that we need to bind to a single element and intercept events as they bubble up the DOM tree.
If the previous methods do the same at the
click event you can rearrange the
example above as this:
Remember, the idea behind event delegation is to bind to a single root element and then wait an intercept events as they bubble up the DOM tree.
One the of the slowest jQuery selectors are pseudo and attribute selectors, so, use this selectors with precaution.
The performance hit is greater in this cases because jQuery can’t take advantage
of a native call. In modern browsers
can help us.
$.each() or $fn.each() loops
Whenever you can, try to use a plain
for (in some modern browsers
even faster than
for) over the jQuery
$.each() function. Also, you can gain
some benefits if you cache in memory the length of your container:
- Efficient jQuery Selectors by Craig Buckler.
- jQuery Performance rules by ArtzStudio.
- jQuery best practices by Stephen A. Thomas.
- jQuery best practices by Greg Franko.
- jQuery proven performance tips & tricks by Addy Osmani.
- DOM Core
Please take this “best practices” with a grain of salt, do your research and see if this recommendations applies in your web clients, in my case, I need to provide support for some older browsers (IE 7/8/9 mostly). ↩