Archive for the jQuery Category

Structuring jQuery For Speed and Efficiency

jQuery-logo.gif I love 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!

Popularity: 10% [?]

Using jQuery to avoid classititis in IE6

IE6 lacks CSS 2 support and as a CSS guy - this generally sucks to deal with. One particular pain point is when stylizing form elements. Sometimes overlooked - it has become one of the first things I usually attack when developing a website. I can’t stand unstylized forms. I tend to leave buttons alone, but slapping a 1px border on input,textarea and select elements can work wonders. But due to lack of CSS 2 support in IE6 there is no easy way to differentiate html elements like these:

<input type="text"/>
<input type="submit" value="submit"/>

This leads to a term Jeffery Zeldman coined as “classititis� - the extraneous use of class assignments in markup. To deal with IE6 I previously would create markup such as this:

<input class="text" type="text" />
<input class="submit"  type="submit" value="submit" />

to give myself the proper style hooks required to differentiate the elements.

With browsers that support CSS2 - Firefox, IE7, Safari, etc (basically every one nowadays except IE6) it is easy to use proper CSS2 selectors

input[type=text] { /* styles /}
input[type=submit] { / styles */}

However, leveraging jQuery and some simple rules can cleanup our markup and avoid classititis. We can even add in sharp focus/blur based styling behaviors for an enhanced prettification of otherwise boring form elements.

Enter jQuery

I am a huge fan of jQuery. I’ve used quite a javascript frameworks but none of them stuck more than jQuery. Between the thriving community, excellent documentation, and plethora of plugins - you can’t go wrong.

I frequently reuse code snippets of useful functions and css rules that I’ve accrued over time (more on my CSS toolkit another time). Here is code that allows me to avoid the trap of classititis due to lack of CSS2 support in IE6:

$(document).ready(function() { 
        $("input[@type=password], input[@type=text]").addClass("text");

    $("input[@type=password], input[@type=text], textarea").focus(function() {
        $(this).addClass("focus"); 
                //focus class provides a hook to alert the user 
    });
    
    $("input[@type=password], input[@type=text], textarea").blur(function(){
        if ($(this).find(".focus")) {
            $(this).removeClass("focus");
        }
    });
});

input type=”text” try typing in some text and taking focus off the input box

textarea

CSS that will pull it all together

input.text, textarea, select {
  color: #777;
  padding: 2px 5px;
  font-size: 110%;
  border: 1px solid #333;
  background: #fafafa;
}
.focus {
  background: #fff !important;
  color: #000 !important;
}

Be sure to check out 456bereastreet for an excellent article on CSS 2.1 selectors.

Popularity: 18% [?]