I am plagiarizing myself!

I originally wrote this article for my friend Moses (of Egypt) to be published in the .Network magazine’s inaugural issue, which coincided with this year’s Cairo Code Camp. Since the article turned out well and there was no corresponding online version, we agreed it would be a good idea to republish it online here too.

Most of us get our first taste of jQuery by implementing a simple animation effect or using a plugin for a specific purpose. This is natural because, like JavaScript itself, jQuery lends itself to beginning with the basics and building from there.

As you branch out from the trivial and begin using jQuery for more complex solutions, it’s important that you stay vigilant for new ways to approach those more involved problems. What works well enough for a dozen lines of code may not work for hundreds, and the unforgiving cross-platform environment that comes along with developing for web browsers only magnifies any trouble you run into.

With that in mind, I want to share a few tips with you that I found valuable as my work with jQuery became more complex.


Use Firebug to experiment interactively

If I could suggest only one thing to you, it would be to use Firebug’s console to prototype your ideas in real time. Nothing matches the command line’s immediate feedback when you’re learning. Rather than go through the hassle of editing a JavaScript file, saving it, and then reloading it in the browser, testing at the console allows you to eliminate those intermediate steps and focus on the task at hand.

In particular, the console is invaluable when testing complex combinations of selectors and traversal methods. Simply execute a jQuery statement at the console, with your page loaded in the browser, and you will instantly see the array of matching elements that are returned. If that result set isn’t correct, press the up-arrow key to retrieve the last command entered, refine the statement, and test it again.

That tight feedback loop is phenomenal for quickly learning the jQuery API without leaving the familiar backdrop of your existing markup.

Additionally, one lesser-known feature of Firebug’s console is how it works in conjunction with Firebug’s debugger. When execution is paused, switching to the console tab allows you to interrogate and manipulate the state of the DOM as it was at the time execution was halted. As you step through JavaScript code in the debugger, the execution context of the console remains in sync with the debugger’s.

Cache selector results

jQuery’s concise syntax makes it easy to forget just how much work the Sizzle selector engine is doing on your behalf. As powerful as the terse selectors are, it’s important not to needlessly duplicate the work that they abstract – especially when using selectors without browser-native backing methods (e.g. a[href^=http], tr:odd, p:contains(Encosia), etc).

To avoid wasteful re-querying, always cache the results of a jQuery selector in a variable if that result set will be used more than once. Once stored in a variable, the result of a selector may be used in exactly the same manner as the original selector itself. For example:

Prefixing the cache variable with a dollar sign is not functionally significant, but helps to clearly indicate that the variable contains a jQuery wrapped set. The topic of Hungarian notation is a contentious one, but I’ve found the dollar sign prefix beneficial as complexity increases.

Don’t use jQuery unless there’s a good reason to

Perhaps one of the most elusive keys to jQuery mastery is knowing when not to use it. Once you’re proficient with jQuery, it seems natural to use it everywhere. However, that tendency may easily mislead you into writing less concise code that runs slower than necessary.

For instance, this egregious example is one that you will see often:

In the context of that callback function, this is a reference to the DOM element that raised the click event – often referred to as the execution context. Rather than using the DOM element to create a jQuery object, with all of the overhead that goes along with that, why not use the DOM element itself?

Another similar misuse is using jQuery as a document.getElementById shortcut. Though jQuery’s ID selector does leverage document.getElementById, it only does so after parsing the selector and then creates a jQuery object to wrap the element. Not only is there more overhead in that process, but starting with a jQuery object by default guides you toward this mistake of overusing jQuery when it isn’t necessary.

Learn advanced selectors, filters, and traversals

A great way to improve your jQuery code is to learn its selectors, filters, and traversal methods in depth. If you find yourself iterating through a selection and manually filtering it for a desired set, there is usually a better way. Double and triple check that there isn’t a combination of selectors, filters, and/or traversals available to accomplish the same end result.

Not only does using the library’s idioms make your code more concise and expressive, but you will automatically benefit from ongoing performance improvements to jQuery’s Sizzle selector engine that come with each new release. It’s hard to beat having an entire team working to improve your code for you, but that’s exactly what happens when you use jQuery syntax that’s as idiomatic as possible.

A less-frequently documented aspect of learning advanced selectors is that you should be conscious of how to work in concert with jQuery to optimize them. Because the Sizzle engine evaluates selectors from right-to-left, being as specific as possible in the rightmost portion of selectors will improve performance.

Selectors that descend from an ID are one notable exception to the right-to-left rule. Sizzle is specially optimized for that case:

Use CDN hosting when available

When you’re developing and testing locally, it’s easy to underestimate the impact that WAN latency will have on your site. Today’s website is often accessed by a geographically diverse set of users that it is impossible to optimally serve all of them from a single datacenter. Serving static resources, such as jQuery, from content delivery networks is one effective solution to mitigate that problem.

Not only do these CDNs provide a faster, more consistent experience to geographically dispersed users, but they also open up the potential for users to visit your site with a primed cache. Since everyone using these public CDNs reference the same URL, a single browser-cached copy of a given asset may be shared between any number of sites visited by a given user.

Even better, because these CDNs serve their content with a far future Expires header, browsers immediately use a locally-cached version of that file if it’s available. They don’t even have to check with the server for a 304 “Not Modified” response, eliminating the extra HTTP request altogether.

Assets freely available on public CDNs include jQuery itself, jQuery UI, all 14 jQuery UI ThemeRoller themes, and the jQuery validation plugin.

Conclusion

I hope that you’ll find these ideas useful on your road to jQuery mastery. Though jQuery’s clear, intuitive syntax may appear simplistic on the surface, the library is immensely powerful. The key to unlocking jQuery’s full potential is to never stop experimenting and learning new aspects of it.

In the spirit of that continued road toward mastery, consider taking the next step by watching my TekPub series: Mastering jQuery.