Structuring jQuery For Speed and Efficiency
I
jQuery. There I said it loud and clear across the Internet so everyone knows it. I don’t ever want to use another framework.
When I work with large sites with many jQuery rules that have to be applied, sometimes this can cause sluggishness – especially if you’re using jQuery for progressive enhancement.
I was recently hit with a performance snag with jQuery – I just had too much going on in my jrules.js file – this is what I use to apply all of my DOM methods with jQuery. jQuery performance is great – and with the packed version it’s footprint is miniscule but when you parse a massive DOM and apply a ton of rules sluggishness ensues especially when using progressive enhancement to hide/show multiple objects.
Right now I have a jrules.js file that is big, mean and has over 200+ lines of jQuery goodness to apply every time a page loads.
I hit performance issues when I have pages with hundreds of tags in the markup and a ton of content – you can see where I’m going with this.
What I came up with and use for most of my recent projects is a way to pass over those jQuery rules that don’t need to be applied or even looked at on certain pages. This is how I go about it:
First I break up my rules according to what page they’re on.
document.ready(function() {
// GLOBAL
// HOME
// LOGIN
});If you can segregate rules and only apply them when they’re needed you’ll significantly improve the speed with which jQuery can handle it all, especially when you’re dealing with massive DOM trees.
I leverage top level CSS inheritance to bring it together. On my pages assign an ID to the body tag from which all my jQuery rules will be executed upon.
<body id="home">
You can use .length or .size() – they’re synonymous to test if the jQuery object is avaiable in the DOM, if it doesn’t exist jQuery doesn’t have to bother with it.
Rules only used on certain pages can now be filtered and jQuery can pass over huge blocks of declarations of whom we know don’t exist in the current DOM anyhow.
document.ready(function() {
// GLOBAL
// DOM elements that exist on every page
$("input[@type=password], input[@type=text]").addClass("text");
$("input[@type=password], input[@type=text], textarea").focus(function() {
$(this).addClass("focus");
});
// HOME body#home
if ($("body#home").size()) {
// only applies rules on the homepage
$("p").hover(function() {
$(this).addClass("change")
}, function() {
$(this).removeClass("change")
);
}
// LOGIN
if ($("body#login").size()) {
// only applies rules on the login page
}
});For simple pages with a few rules and a small DOM this is definitely overkill, but if you’ve noticed even a nano second of lag when jQuery applies your rules and see the DOM rearrange itself at page load try this out and let me know how it worked for you.
Last night when I attended a meeting of The Markup & Style Society at the Filament Group office. I got a chance to speak with Mr. jQuery himself – John Resig about my performance issue and I shared my solution to the problem. I was unsure I approached it the best way and there wasn’t a better solution available out there, but he assured me the way I was going about it was sound so consider this method Resig Approved™.
UPDATE
John alerted me to this: Seems that jQuery is now more popular than Prototype – far as search queries go at least. Congrats John & the jQuery team!

Very cool man. I had to miss out on the M&SS meetup; was totally bummed.
I wrote about a similar technique of organizing onload handlers here: http://paulirish.com/2008/automate-firing-of-onload-events/
left this nugget of wisdom March 15th, 2008 at 8:58 pm