Improve your jQuery - 25 excellent tips

14 Dec 2008 | Jon Hobbs-Smith

Introduction



jQuery is awesome. I've been using it for about a year now and although I was impressed to begin with I'm liking it more and more the longer I use it and the more I find out about it's inner workings.

I'm no jQuery expert. I don't claim to be, so if there are mistakes in this article then feel free to correct me or make suggestions for improvements.

I'd call myself an "intermediate" jQuery user and I thought some others out there could benefit from all the little tips, tricks and techniques I've learned over the past year. The article also ended up being a lot longer than I thought it was going to be so I'll start with a table of contents so you can skip to the bits you're interested in.

Table of Contents






1. Load the framework from Google Code



Google have been hosting several JavaScript libraries for a while now on Google Code and there are several advantages to loading it from them instead of from your server. It saves on bandwidth, it'll load very quickly from Google's CDN and most importantly it'll already be cached if the user has visited a site which delivers it from Google Code.

This makes a lot of sense. How many sites out there are serving up identical copies of jQuery that aren't getting cached? It's easy to do too...

<script src="http://www.google.com/jsapi"></script>
<script type="text/javascript">

    // Load jQuery
    google.load("jquery", "1.2.6");

    google.setOnLoadCallback(function() {
        // Your code goes here.
    });
       
</script>

Or, you can just include a direct reference like this...

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script>

Full instructions here


2. Use a cheat sheet



Not just a jQuery tip, there are some great cheat sheets out there for most languages. It's handy having every function on a printable A4 sheet for reference and luckily these guys have produced a couple of nice ones..

http://www.gscottolson.com/weblog/2008/01/11/jquery-cheat-sheet/
http://colorcharge.com/jquery/


3. Combine all your scripts and minify them



OK, a general JavaScript tip here. But any big project that uses lots of jQuery probably uses lots of plugins (this site uses easing, localScroll, lightbox and preload) so it's usually applicable.

Browsers can't load scripts concurrently (well, most can't, yet), which means that if you've got several scripts downloading one at a time then you're really slowing down the loading of your page. So, assuming the scrips are being loaded on every page then you should consider combining them into one long script before deploying.

Some of the plugins will already be minified, but you should consider packing your scripts and any that aren't already. It only takes a few seconds. I'm personally a fan of Packer by Dean Edwards


4. Use Firebug's excellent console logging facilities



If you haven't already installed Firebug then you really should. Aside from many other useful features such as allowing you to inspect http traffic and find problems with your CSS it has excellent logging commands that allow you to easily debug your scripts.

Here's a full explanation of all of it's features

My favourite features are "console.info", which you can use to just dump messages and variables to the screen without having to use alert boxes and "console.time" which allows you to easily set up a timer to wrap a bunch of code and see how long it takes. They're all really easy to use too...

console.time('create list');

for (i = 0; i < 1000; i++) {
    var myList = $('.myList');
    myList.append('This is list item ' + i);
}

console.timeEnd('create list');

In this instance I've deliberately written some very inefficient code! In the next few tips I'll show you how we can use the timer to show some improvements which can be made.



5. Keep selection operations to a minimum by caching



jQuery selectors are awesome. They make selecting any element on the page incredibly simple, but internally they have to do a fair amount of work and if you go mad with them you might find things starting to get pretty slow.

If you're selecting the same element time and time again (in a loop for example) then you can just select it once and keep it in memory while you manipulate it to your heart's content. Take the following example where we add items to an unordered list using a loop.

for (i = 0; i < 1000; i++) {
    var myList = $('.myList');
    myList.append('This is list item ' + i);
}

That takes 1066 milliseconds on my PC in Firefox 3 (imagine how long it would IE6!), which is pretty slow in JavaScript terms. Now take a look at the following code where we use the selector just once.

var myList = $('.myList');

for (i = 0; i < 1000; i++) {
    myList.append('This is list item ' + i);
}

That only takes 224 milliseconds, more than 4x faster, just by moving one line of code.



6. Keep DOM manipulation to a minimum



We can make the code from the previous tip even faster by cutting down on the number of times we insert into the DOM. DOM insertion operations like .append() .prepend() .after() and .wrap() are relatively costly and performing lots of them can really slow things down.

All we need to do is use string concatenation to build the list and then use a single function to add them to your unordered list like .html() is much quicker. Take the following example...

var myList = $('#myList');

for (i=0; i<1000; i++){
    myList.append('This is list item ' + i);
}

On my PC that takes 216 milliseconds , just over a 1/5th of a second, but if we build the list items as a string first and use the HTML method to do the insert, like this....

var myList = $('.myList');
var myListItems = '';

for (i = 0; i < 1000; i++) {
    myListItems += '<li>This is list item ' + i + '</li>';
}

myList.html(myListItems);

That takes 185 milliseconds, not much quicker but that's another 31 milliseconds off the time.



7. Wrap everything in a single element when doing any kind of DOM insertion



OK, don't ask me why this one works (I'm sure a more experienced coder will explain).

In our last example we inserted 1000 list items into an unordered list using the .html() method. If we had have wrapped them in the UL tag before doing the insert and inserted the completed UL into another tag (a DIV) then we're effectively only inserting 1 tag, not 1000, which seems to be much quicker. Like this...

var myList = $('.myList');
var myListItems = '<ul>';

for (i = 0; i < 1000; i++) {
    myListItems += '<li>This is list item ' + i + '</li>';
}

myListItems += '</ul>';
myList.html(myListItems);

The time is now only 19 milliseconds, a massive improvement, 50x faster than our first example.



8. Use IDs instead of classes wherever possible



jQuery makes selecting DOM elements using classes as easy as selecting elements by ID used to be, so it's tempting to use classes much more liberally than before. It's still much better to select by ID though because jQuery uses the browser's native method (getElementByID) to do this and doesn't have to do any of it's own DOM traversal, which is much faster. How much faster? Let's find out.

I'll use the previous example and adapt it so each LI we create has a unique class added to it. Then I'll loop through and select each one once.

// Create our list
var myList = $('.myList');
var myListItems = '<ul>';

for (i = 0; i < 1000; i++) {
    myListItems += '<li class="listItem' + i + '">This is a list item</li>';
}

myListItems += '</ul>';
myList.html(myListItems);

// Select each item once
for (i = 0; i < 1000; i++) {
    var selectedItem = $('.listItem' + i);
}

Just as I thought my browser had hung, it finished, in 5066 milliseconds (over 5 seconds). So i modified the code to give each item an ID instead of a class and then selected them using the ID.

// Create our list
var myList = $('.myList');
var myListItems = '<ul>';

for (i = 0; i < 1000; i++) {
    myListItems += '<li id="listItem' + i + '">This is a list item</li>';
}

myListItems += '</ul>';
myList.html(myListItems);

// Select each item once
for (i = 0; i < 1000; i++) {
    var selectedItem = $('#listItem' + i);
}

This time it only took 61 milliseconds. Nearly 100x faster.



9. Give your selectors a context



By default, when you use a selector such as $('.myDiv') the whole of the DOM will be traversed, which depending on the page could be expensive.

The jQuery function takes a second parameter when performing a selection.

jQuery( expression, context )

By providing a context to the selector, you give it an element to start searching within so that it doesn't have to traverse the whole of the DOM.

To demonstrate this, let's take the first block of code from the tip above. It creates an unordered list with 1000 items, each with an individual class. It then loops through and selects each item once. You'll remember that when selecting by class it took just over 5 seconds to select all 1000 of them using this selector.

var selectedItem = $('#listItem' + i);

I then added a context so that it was only running the selector inside the unordered list, like this...

var selectedItem = $('#listItem' + i, $('.myList'));

It still took 3818 milliseconds because it's still horribly inefficient, but that's more than a 25% speed increase by making a small modification to a selector.



10. Use chaining properly



One of the coolest things about jQuery is it's ability to chain method calls together. So, for example, if you want to switch the class on an element.

$('myDiv').removeClass('off').addClass('on');

If you're anything like me then you probably learned that in your first 5 minutes of reading about jQuery but it goes further than that. Firstly, it still works across line breaks (because jQuery = JavaScript), which means you can write neat code like this...

$('#mypanel')
    .find('TABLE .firstCol')
    .removeClass('.firstCol')
    .css('background' : 'red')
    .append('<span>This cell is now red</span>');

Making a habit of using chaining automatically helps you to cut down on your selector use too.

But it goes further than that. Let's say that you want to perform several functions on an element but one of the first functions changes the element in some way, like this...

$('#myTable').find('.firstColumn').css('background','red');

We've selected a table, drilled down to find cells with a class of "firstColumn" and coloured them in red.

Let's say we now want to colour all the cells with a class of "lastColumn" blue. Because we've used the find() funciton we've filtered out all the cells that don't have a class of "firstColumn" so we need to use the selector again to get the table element and we can't continue chaining, right? Luckily jQuery has an end() function which actually reverts back to the previous unaltered selection so you can carry on chaining, like this...

$('#myTable')
    .find('.firstColumn')
        .css('background','red')
    .end()
    .find('.lastColumn')
        .css('background','blue');

It's also easier than you might think to write your own jQuery function which can chain. All you have to do is write a function which modifies an element and returns it.

$.fn.makeRed = function() {
    return $(this).css('background', 'red');
}

$('#myTable').find('.firstColumn').makeRed().append('hello');

How easy was that?



11. Learn to use animate properly



When I first started using jQuery I loved the fact that it was easy to use the pre-defined animations like slideDown() and fadeIn() to get some really cool effects incredibly easy. It's easy to take things further though because jQuery's animate() method is very easy to use and very powerful. In fact, is you look at the jQuery source code you'll see that internally those methods are just shortcuts which use the animate() function.

slideDown: function(speed,callback){
    return this.animate({height: "show"}, speed, callback);
},

fadeIn: function(speed, callback){
    return this.animate({opacity: "show"}, speed, callback);
}

The animate() method simply takes any CSS style and smoothly transitions it from one value to another. So, you can change the width, height, opacity, background-color, top, left, margin, color, font-size, anything you want.

This is how easy it is to animate all your menu items grow to 100 pixels high when you roll over them.

$('#myList li').mouseover(function() {
    $(this).animate({"height": 100}, "slow");
});

Unlike other jQuery functions, animations are automatically queued, so if you want to run a second animation once the first is finished then just call the animate method twice, no callback necessary.

$('#myBox').mouseover(function() {
    $(this).animate({ "width": 200 }, "slow");
    $(this).animate({"height": 200}, "slow");
});

If you want the animations to happen concurrently then just put both styles in the params object of a single call, like this...

$('#myBox').mouseover(function() {
    $(this).animate({ "width": 200, "height": 200 }, "slow");
});

You can animate any property that's numeric. You can also download plugins to help you animate properties that aren't, like colors and background colors


12. Learn about event delegation



jQuery makes it easier than ever to attach events to elements in the DOM unobtrusively, which is great, but adding too many events is inefficient. Event delegation allows you to add less events to achieve the same result in many situations. The best way to illustrate this is with an example...

$('#myTable TD').click(function(){
    $(this).css('background', 'red');
});

A simple function which turns cells in a table red when you click on them. Let's say that you've got a grid with 10 columns and 50 rows though, that's 500 events bound. Wouldn't it be neater if we could just attach a single event to the table and when the table is clicked have the event handler work out which cell was clicked before turning it red?

Well that's exactly what event delegation is and it's easy to implement...

$('#myTable').click(function(e) {
    var clicked = $(e.target);
    clicked.css('background', 'red');
});

'e' contains information about the event, including the target element that actually received the click. All we have to do is inspect it to see which cell was actually clicked. Much neater.

Event delegation has another benefit. Normally, When you bind a handler to a collection of elements it gets attached to those elements and those elements only. If you add new elements to the DOM which would have been matched by the selector then they don't have the event handler bound to them (are you following me?) then nothing will happen.

When using event delegation you can add as many matching elements to the DOM as you like after the event is bound and they work too.



13. Use classes to store state



This is the most basic way of storing information about a block of html. jQuery is great at manipulating elements based upon their classes, so if you need to store information about the state of an element then why not add an extra class to store it?

Here's an example. We want to create an expanding menu. When you click the button we want the panel to slideDown() if it's currently closed, or slideUp() if it's currently open. We'll start with the HTML

<div class="menuItem expanded">
    <div class="button">
        click me
    </div>
    <div class="panel">
        <ul>
            <li>Menu item 1</li>
            <li>Menu item 2</li>
            <li>Menu item 3</li>
        </ul>
    </div>
</div>

Very simple! We've just added an extra class to the wrapper div which serves no other purpose other than to tell us the state of the item. So all we need is a click event handler which performs slideUp() or slideDown() on the corresponding panel when the button is clicked.

$('.button').click(function() {

    var menuItem = $(this).parent();
    var panel = menuItem.find('.panel');

    if (menuItem.hasClass("expanded")) {
        menuItem.removeClass('expanded').addClass('collapsed');
        panel.slideUp();
    }
    else if (menuItem.hasClass("collapsed")) {
        menuItem.removeClass('collapsed').addClass('expanded');
        panel.slideDown();
    }
});

That's a very simple example, but you can add extra classes for storing all sorts of information about an element or HTML fragment.

However, in all but simple cases it's probably better to use the next tip.



14. Even better, use jQuery's internal data() method to store state



It's not very well documented for some reason but jQuery has an internal data() method which can be used to store information in key/value pairs against any DOM element. Storing a piece of data is as simple as this...

$('#myDiv').data('currentState', 'off');

We can amend the example from the previous tip. We'll use the same HTML (with the "expanded" class removed) and use the data() function instead.

$('.button').click(function() {

    var menuItem = $(this).parent();
    var panel = menuItem.find('.panel');

    if (menuItem.data('collapsed')) {
        menuItem.data('collapsed', false);
        panel.slideDown();  
    }
    else {
        menuItem.data('collapsed', true);
        panel.slideUp();
    }
});

I'm sure you'll agree this is much neater. For more information about data() and removeData(), see this page...

jQuery internals


15. Write your own selectors



jQuery has loads of built-in selectors for selecting elements by ID, class, tag, attribute and many more. But what do you do when you need to select elements based upon something else and jQuery doesn't have a selector?

Well, one answer would be to add classes to the elements from the start and use those to select them, but it turns out that it's not hard to extend jQuery to add new selectors.

The best way to demonstrate is with an example.

$.extend($.expr[':'], {
    over100pixels: function(a) {
        return $(a).height() > 100;
    }
});

$('.box:over100pixels').click(function() {
    alert('The element you clicked is over 100 pixels high');
});

The first block of code creates a custom selector which finds any element that is more than 100 pixels tall. The second block just uses it to add a click handler to all those elements.

I won't go into any more detail here but you can imagine how powerful this is and if you search google for "custom jquery selector" you'll find loads of great examples.



16. Streamline your HTML and modify it once the page has loaded



The title might not make a lot of sense but this tip can potentially neaten up your code, reduce the weight and download time of your page and help your SEO. Take the following HTML for example...

<div class="fieldOuter">
    <div class="inner">
        <div class="field">This is field number 1</div>
    </div>
    <div class="errorBar">
        <div class="icon"><img src="icon.png" alt="icon" /></div>
        <div class="message"><span>This is an error message</span></div>
    </div>
</div>
<div class="fieldOuter">
    <div class="inner">
        <div class="field">This is field number 2</div>
    </div>
    <div class="errorBar">
        <div class="icon"><img src="icon.png" alt="icon" /></div>
        <div class="message"><span>This is an error message</span></div>
    </div>
</div>

That's an example of how a form might be marked up, modified slightly for illustrative purposes. I'm sure you'll agree it's pretty ugly and if you had a long form you'd end up with a fairly long ugly page. It's be nicer if you could just put this in your HTML.

<div class="field">This is field 1</div>
<div class="field">This is field 2</div>
<div class="field">This is field 3</div>
<div class="field">This is field 4</div>
<div class="field">This is field 5</div>

All you have to do is a bit of jQuery manipulation to add all the ugly HTML back in. Like this...

$(document).ready(function() {
    $('.field').before('<div class="fieldOuter"><div class="inner">');
    $('.field').after('</div><div class="errorBar"><div class="icon">
        <img src="icon.png" alt="icon" /></div><div class="message">
        <span>This is an error message</span></div></div></div>');
});

It's not always advisable to do this, you'll get a bit of a flash as the page loads, but in certain situations where you've got a lot of repeated HTML it can really reduce your page weight and the SEO benefits of reducing all your repeated extraneous markup should be obvious.



17. Lazy load content for speed and SEO benefits



Another way to speed up your page loads and neaten up the HTML that search spiders see is to lazy load whole chunks of it using an AJAX request after the rest of the page has loaded. The user can get browsing right away and spiders only see the content you want them to index.

We've used this technique on our own site. Those purple buttons at the top of the page drop down 3 forms, directions and a google map, which was doubling the size of our pages. So, we just put all that HTML in a static page and use the load() function to load it in once the DOM was ready. Like this...

$('#forms').load('content/headerForms.html', function() {
    // Code here runs once the content has loaded
    // Put all your event handlers etc. here.            
});

I wouldn't use this everywhere. You have to consider the trade offs here. You're making extra requests to the server and portions of your page might not be available to the user right away, but used correctly it can be a great optimization technique.



18. Use jQuery's utility functions



jQuery isn't just about flash effects. The creator has exposed some really useful methods which fill a few gaps in JavaScript's repertoire.

http://docs.jquery.com/Utilities

In particular, browser support for certain common array functions is patchy (IE7 doesn't even have an indexOf() method!). Jquery has methods for iterating, filtering, cloning, merging and removing duplicates from Arrays.

Other common functions that are difficult in Javascript include getting the selected item in a drop down list. In plain old JavaScript you'd have to get the <select> element using getElementByID, get the child elements as an array and iterate through them checking whether each one was selected or not. jQuery makes it easy...

$('#selectList').val();

It's worth spending some time looking through the jQuery documentation on the main site and having a nose around some of the lesser known functions.



19. Use noconflict to rename the jquery object when using other frameworks



Most javascript frameworks make use of the $ symbol as a shorthand and this can cause clashes when trying to use more than one framework on the same page. Luckily there's a simple solution. The .noconflict() function gives control of the $ back and allows you to set your own variable name, like this...

var $j = jQuery.noConflict();
$j('#myDiv').hide();



20. How to tell when images have loaded



This is another one of those problems that doesn't seem to be as well documented as it should be (not when I went looking anyway) and it's a fairly common requirement when building photo galleries, carousels etc, but it's fairly easy.

All you have to do is use the .load() method on an IMG element and put a callback function in it. The following example changes the "src" attribute of an image tag to load a new image and attaches a simple load function.

$('#myImage').attr('src', 'image.jpg').load(function() {
    alert('Image Loaded');
});

You should find that the alert is called as soon as the image is loaded.



21. Always use the latest version



jQuery is constantly improving and John Resig, it's creator, always seems to be in search of ways to improve performance.

jQuery is currently on version 1.2.6 but John has already revealed that he's working on a new selector engine called Sizzle, which may apparently improve selector speeds in Firefox by up to 4x. So, it pays to keep up to date.



22. How to check if an element exists



You don't need to check if an element exists on the page before you manipulate it because jQuery will will simply do nothing if you try to select something and it isn't in the DOM. But when you do need to check if anything has been selected, or how many items have been selected you can use the length property.

if ($('#myDiv).length) {
    // your code
}

Simple, but not obvious.



23. Add a JS class to your HTML attribute



I learned this tip from Karl Swedberg whose excellent books I used to learn jQuery.

He recently left a comment on one of my previous articles about this technique and the basics are as follows...

Firstly, as soon as jQuery has loaded you use it to add a "JS" class to your HTML tag.

$('HTML').addClass('JS');

Because that only happens when javascript is enabled you can use it to add CSS styles which only work if the user has JavaScript switched on, like this...

.JS #myDiv{display:none;}

So, what this means is that we can hide content when JavaScript is switched on and then use jQuery to show it when necessary (e.g. by collapsing some panels and expanding them when the user clicks on them), while those with JavaScript off (and search engine spiders) see all of the content as it's not hidden. I'll be using this one a lot in the future.

To read his full article click here.



24. Return 'false' to prevent default behaviour



This should be an obvious one but maybe not. if you have a habit of doing this...

<a href="#" class="popup">Click me!</a>

... and then attaching an event handler like this...

$('popup').click(function(){
    // Launch popup code
});

... it'll probably work fine until you use it on a long page, at which point you'll notice that the # is causing it to jump to the top of the page when your click event is triggered.

All you have to do to prevent this default behaviour, or indeed any default behaviour on any event handler is to add "return false;" to your handler, like this...

$('popup').click(function(){
    // Launch popup code
    return false;
});



25. Shorthand for the ready event



A small tip this one but you can save a few characters by using shorthand for the $(document).ready function.

Instead of this...

$(document).ready(function (){
    // your code
});

You can do this...

$(function (){
    // your code
});

If you enjoyed this article please digg it:


Tags:

comments

Derek Pennycuff @ 16 Dec 2008 4:15 PM

Great article. One tiny mistake. In #8 you say nearly 10x faster. You mean nearly 100x faster. :)

Eric Martin @ 16 Dec 2008 4:23 PM

Great write-up Jon! One thing I would change to the second example in #25:
jQuery(function ($) {
// now you can use $ without conflicts
});

Brenley Dueck @ 16 Dec 2008 5:51 PM

Excellent Article! I appreciate all the tips and tricks in regards to performance and better use of JQuery. Definitely be using some of these in the future!

Vimal @ 16 Dec 2008 8:28 PM

Very good article. It really helps. Great work.

Bjoern @ 16 Dec 2008 8:56 PM

Excellent article. However, if you follow the instructions of 1, keep in mind, that Google is able to track you and your users then. If you already use other Google services on your page, you may not care about this point. But if not, I think this is a very expensive way for a little more speed.

Jon @ 16 Dec 2008 9:36 PM

@Derek - Thanks, I've changed it.

@Eric - Combining tips! I like it.

@Bjoern - I personally don't have any problem with google and like using Google Analytics. I'll change my mind if they ever do anything to break that trust.

Chris @ 16 Dec 2008 9:49 PM

great stuff, will use this for reference later :)

Mike Branski @ 16 Dec 2008 11:05 PM

Fantastic article. One note: the link at the bottom of tip #11 is broken. The text is right if you copy/paste, but the href is incorrect.

Jon @ 16 Dec 2008 11:33 PM

@Mike - Thanks, fixed the link.

Paul Irish @ 16 Dec 2008 11:34 PM

#9: I cant believe that providing a context of ".className" would be faster than straight getElementById checks. So I think your example is poor. You may want to recheck that.
But more importantly, doing $("div.block",$("#container")) is no faster than $("#container div.block")
Nevertheless, many developers dont optimize their selectors, which is the larger point youre making.. :)

EDIT: and is it me or does your ajax comment system totally choke if there are apostrophes?

Jon @ 16 Dec 2008 11:49 PM

@ Paul - Thanks for the comments. All the timings are straight from Firebug. I realise that $("#container div.block") would be easier but as I said a few times in the article some of the code is there purely to illustrate a point.

As for the comment system, it's still new so I wouldn't be surprised if there's a few little bugs in it. I'll look into it ;)

szinspire @ 17 Dec 2008 1:48 AM

very very excellent article~~~~~ GREAT WORK!

Zaiman Noris @ 17 Dec 2008 5:01 AM

In example #24, you missed the dot for classes.
Anyhoo, great article.

Kean @ 17 Dec 2008 8:31 AM

Sweet tutorial, love to see more coming from you! I learned at least 10 things from your list.

Andy Jeffries @ 17 Dec 2008 8:39 AM

Another dull comment with not much to add, but I just wanted to add my congratulations - this is an awesome article!

Eduardo Sasso @ 17 Dec 2008 9:10 AM

Great tips. Congratulations for the excellent article.

Gaurav @ 17 Dec 2008 9:27 AM

Great Article !! Some of the tips are really helpful. I learnt couple of new things about jQuery and rest will improve my coding.



Mark @ 17 Dec 2008 9:29 AM

Wow. Great article! Very useful tips. A lot of these are new to me :)

Oliver Schlöbe @ 17 Dec 2008 10:17 AM

Tip 19 should be a Must. Always use jQuery() instead of $()! This is working without using noConflict(), and you dont have to manually change it afterwards if there's another framework added to the site later sometime...

Larry Battle @ 17 Dec 2008 10:43 AM

Wondeful tips, Jon!
I didn't know firebug's console had a performance timer. console.time( string ) is kick ass.

#22: Needs a single quote at the end. $( '#myDiv' )

Peter Kahoun @ 17 Dec 2008 11:08 AM

Nice one!

Typo found: $('popup').click... => $('.popup').click...

ze @ 17 Dec 2008 11:50 AM

Nice Job men!
Thanks!

Mikel @ 17 Dec 2008 12:18 PM

Very well done man! Thats the best article about jQuery. Thanks

Alex @ 17 Dec 2008 12:21 PM

This Tips are very very Excellent
Thx

Paul @ 17 Dec 2008 2:11 PM

Some great tips there, and ones I am sure to use in my next project. I do have a slight problem with #16 though (inserting HTML using JS). As well as the 'flash' you described, if a user has JS disabled, or hasn't got it installed, those elements will never show, and I think it might be a little *too* far in terms of streamlining.

Enhancements are fine, but disregarding users without JS is a no-no personally. If it is used, a message should appear stating that some things need JS to work

Daniele @ 17 Dec 2008 3:08 PM

Nice article, I agreed with most stuff, albeit some things are (or will be) trivial (the upcoming browser will support better css-like selection, so the getElementById won't be so prominent).

Also #16 is outright wrong, stop suggesting to use js to inject html that does the job which was meant to be done by css.

Jon @ 17 Dec 2008 3:10 PM

@Daniele - I did say that not all of these tips would be right for everyone. I do disagree about tip 16 though. In an ideal world all our markup would be semantic. Unfortunately CSS is inflexible and often forces us to use a lot of extra non-sementic markup.

I do agree with making these things progressive wherever possible.

Jeremy Martin @ 17 Dec 2008 3:21 PM

Regarding #7, this has to do with reducing the number of modifications on the DOM. In your example, while you're building your UL and it's children, you're only modifying a small object in memory - which is far less expensive than modifying the much larger and more "context aware" nodes on the DOM. When you modify the DOM, the browser sends internal notifications all over the place to keep the various engines up to date - hence the slower performance. You hinted at the answer in #6. Good post!

malsup @ 17 Dec 2008 3:50 PM

Excellent article, Jon! One point of clarification: In item #16 you're examples incorrectly suggest that the DOM manipulation methods (before, after, etc) can take 'partial' markup. That is not the case. You insert elements, not text, so you should *not* do this:

$('.field').before('');

rather, that is what the "wrap" function is for:

$('.field').wrap('');
.

Daniele @ 17 Dec 2008 4:03 PM

@Jon: I can't really help it, I still think it's a push in the wrong direction, less mantainable code, no separation etc... Adding a span with a class that gets filled with css might be a slightly less awful solution, but unless you need to float that icon like this
xx ---
xx ---
------
------

you can do it with css. And do it today, abusing serverside scripts to support way too old browsers in spite of
semantics is a big no-no.

Happy Steve @ 17 Dec 2008 4:14 PM

This is truly an excellent article. Thanks for this.

One question though, at the end of tip 9, you use this:

var selectedItem = $('#listItem' + i, $('.myList'));

I'm surprised you didn't employ tip #5 and used the cached version instead:

var selectedItem = $('#listItem' + i, myList);

In fact, I'm surprised there was a drop in execution time at all. Wouldn't it have had to try to find the collection of classes each time inside the for loop?

webninja @ 17 Dec 2008 4:22 PM

Probably the best jQuery article I've read so far.

Thanks for all of this, it'll surely improve my jQuery-no-jutsu.

Baz L @ 17 Dec 2008 4:26 PM

Excellent post, but I got a question:
#12 - using event delegation: Sounds like an excellent idea, however, what happens when the user clicks on a link INSIDE the TD. How do you control what sub-elements the events get delegated to?

Mauro De Giorgi @ 17 Dec 2008 4:35 PM

Great article!
I found a mistake in #9: you say that you select a class, but you select an id:

var selectedItem = $('#listItem' + i);


Matt @ 17 Dec 2008 4:36 PM

This is the most lucid jquery tutorial I've encountered - thank you!

Zach Leatherman @ 17 Dec 2008 5:00 PM

Great writeup.

I agree though that #16 is probably unwise, especially considering the performance overhead. If JavaScript is disabled on the client, the resulting markup will not be correctly interpreted using CSS and your components will not display correctly.

Gregory @ 17 Dec 2008 5:41 PM

Tip #7 amazed me with 3x speed improvements in a list of only about 700 items. Thank you for that!

gregf @ 17 Dec 2008 6:06 PM

Wow, awesome write up. #25 is some stupid on my part but has been bugging me for a while now.

Diego @ 17 Dec 2008 6:27 PM

Good stuff man, I've been getting a lot into JQuery too and these hints definitely help out. You point out a lot of simple but not obvious things.

The tips on performance were particularly enlightening.

Mark Gremmen @ 17 Dec 2008 8:00 PM

I really LOVE jquery. This article is very helpful, some great tips here. Tip 14 was quite new to me.
I do use number 17 all over my domain to load massive hierarchical menu's, dropdown select lists and to
'hide' standard content.

Ben Clemens @ 17 Dec 2008 9:41 PM

Again, great article, many thanks. I have a question: I've been working with a sort of "dispatcher" function written with jquery, to capture all events (e.g clicks) on a page, check the id of the entity being clicked against a list of functions & send if there's a match (with return false), and if there isn't a match return true (in the case of an ordinary link being clicked, etc.). The idea is that the dispatcher can avoid the need for one event handler per element class/id, and no issues with bubbling of events, etc. as elements are inserted into the DOM. Does this sound like a good idea, or a bad one? What would you recommend? Thanks, Ben

Jason @ 17 Dec 2008 10:31 PM

This is an excellent article. Many thanks for the effort. With people like you taking the time, Teh interwebznetz ain't a bad place to be.

For #12(b), could it be written as:

$(e.target).css('background', 'red');

?

Dr. Scotty Delicious, DFPA @ 18 Dec 2008 1:00 AM

Bookmarked!
Great article. Thanks for your research and for sharing it back with the rest of us.

Marc Eilhard @ 18 Dec 2008 8:47 AM

This is by far the best List of jQuery tips I've seen the last months!
Thank you! And Bookmarked!

Brett @ 18 Dec 2008 10:15 AM

Awesome tips! Great article! I certainly have to work on my page-loading speeds more. The firebug tip is great! Thanx!

malsup @ 18 Dec 2008 12:17 PM

gah! I just noticed that my previous comment didn't display the markup. Trying again:

Don't do this:

$('.field').before('<div>');
$('.field').after('</div>');

instead, do this:

$('.field').wrap('<div></div>');

Tom Kenny @ 18 Dec 2008 1:04 PM

A fantastic list that will most definitely help me in the future.

I'm not too sure about hosting the library on google. I don't have a problem with it being google but the fact that its hosted externally and totally out of your control doesn't sit well with me. I like the idea of it being cached from any other site that links to it but if it ever went down for ANY reason then it would break the jQuery functionality. I know that its unlikely that the code will be removed in the near future but anything could happen.

Jon @ 18 Dec 2008 1:24 PM

@Ben Clemens - Have you seen this? http://www.danwebb.net/2008/2/8/event-delegation-made-easy-in-jquery

@malsup - I've tried to use .wrap() in those situations before but doesn't that require you to have perfectly nested elements like this - '<open><open><open>CONTENT</close></close></close>' ?

If you wanted something like this - '<open>CONTENT</close><open></close><open></close><open></close>', then how would you tell it where to put the content?

For me, tip 16 is no different to using client tenplating solutions like 'trimpath' or 'pure', as long as your solution degrades gracefully then I don't see a problem.




Jon @ 18 Dec 2008 1:36 PM

@Tom Kenny - I figure that Google probably have the most reliable hosting in the world, reliable than any hosting you could buy from anybody else, so I can't see that being a problem.

Tom Kenny @ 18 Dec 2008 3:03 PM

@Jon - I seem to remember gmail going down before on more than one occasion so not even google are immune to downtime. Like I said its probably unlikely that anything would happen but you never know.

Adam Backstrom @ 19 Dec 2008 2:15 AM

"Google has been hosting," not "Google have been hosting." Google is a single entity, a company. I can has cheezburger?

Matthew Donadio @ 19 Dec 2008 4:47 PM

Regarding #20, I have run into instances where the callback doesn't fire in some browsers when the image is already cached. In cases like this, you need to check $img.complete do the appropriate action.

Felix Nagel @ 19 Dec 2008 8:08 PM

Great Article, thanks so much.

But one little conceptual mistake @23. Add a JS class to your HTML attribute:
A much better way is hiding the element by css per default, then showing them by JQuery. If you first show them, they will be visible until the Script is loaded and DOM is ready.

THX, greetings

Gabriel Svennerberg @ 19 Dec 2008 11:32 PM

Awesome tips, Thanks a lot!

I do however, like many others, object to the use of tip #16. This technique doesn't degrade properly since users with Javascript disabled and CSS enabled will get a worser experience than necessary. It also mixes content and style in an appropriate way.

In tip #17 there's also an accessibility problem since users with no Javascript will not see this content. So if you use this technique you have to make sure not to lazy load any critical content.

Sean @ 20 Dec 2008 12:05 AM

Some good tips in here, thanks. These "top 10" (or 25 in you case) style posts that are always on digg are usually just pure hogwash, but this one actually gave me a lot of good ideas, so thanks!

Marian P. @ 21 Dec 2008 10:50 AM

It helped me a lot, especially the event delegation method that solved the problem of manipulating inline ajax dom. Thanks for the great article.

Michiel @ 22 Dec 2008 5:19 PM

A tip I got from a friend: when making vars of jQuery objects, always prefix them with a $. e.g. $this = $(this); This will help you keep track of which vars are jQuery objects and which aren't.

khelll @ 22 Dec 2008 10:06 PM

Very nice article,
I would add a suggestion if u don't mind, and which i find it very useful thing: add $ as a prefix to any js variable that holds a jquery element like doing : var $selected = $('#some_id')

Peter Sellars @ 23 Dec 2008 1:55 AM

Thanks you very much. Excellent article. Learnt some great new JQuery tips here.

Tend to agree with the comments on tip #16, but if there was no discussion on these things how would we ever determine best practices. :-)

Your time and effort to document these tips is much appreciated.

Am impressed by the comment form too....you should write an article about it (if you have not done so already) :-)

Emmanuel @ 23 Dec 2008 11:59 PM

Excellent article. I really liked it. on 24 you can even prevent the default link clicking by addind he following code

$('popup').click(function(e){
e.preventDefault();
// Launch popup code
return false;
});

Ian Roke @ 24 Dec 2008 11:15 AM

Hi there, great article. I have bookmarked it for the tips.

I have done a post on my blog about Google hosting the files which people might find useful. The URL is http://blog.ianroke.co.uk/2008/differences-between-local-and-google-hosted-jquery-installations/ if you are interested.

Cheers, Ian.

Vi @ 26 Dec 2008 6:51 PM

First Item should be the opposite: - never load jQuery from Google. Lately Google is suffering from quite frequent slowdowns. I changes all my websites to jQuery local hosting with unbelievable loading speed improvements.

Philip Pryce @ 27 Dec 2008 9:55 PM

Just thought i should mention your missing a period on the jQuery selector on tip 24. $('popup') should be $('.popup').

Teun Roodvoets @ 29 Dec 2008 11:05 AM

Thanks, Jon, for the great tips and examples!

In #9 the text and the example don't match: the text says: "... each with an individual CLASS". But in the example identifiers are being used insteas of classes. I assume both code samples need to be changed from:
$('#listItem' + i
into:
$('.listItem' + i

Cheers,
Teun.

Nate Klaiber @ 30 Dec 2008 8:26 PM

I seem to remember there being issues with only returning false:

$('popup').click(function(){
// Launch popup code
return false;
});

I normally do:

$('popup').click(function(e){
// Launch popup code
e.preventDefault();
});

Thoughts?

M. David Green @ 31 Dec 2008 6:26 PM

I was reading through this excellent list--and making copious notes to myself--when I came across item #16. Looked like it was going to be controversial. I can see from the previous comments that is was. I'm all for HTML optimization and clean mark-up, but solutions like this are hell to maintain in a team environment, and difficult to degrade cleanly.

I think the best way this could be applied is like compression at deployment. That way you can maintain a separate source version of the mark-up that retains all the original structures. In general I prefer not to create new HTML elements in Javascript if at all possible.

B @ 7 Jan 2009 8:53 PM

Awesome post, thanks !!!
had one question regarding binding events using jquery rather than using the the onclick function from with in the html markup
As I understand binding events using JQuery would present two issues:
1) The time taken to traverse the DOM to bind each event.
2) Having to wait for the page to load before any of the javascript becomes available to the user. This would mean that even for trivial event such as hiding/showing divs onclick would be unavailable to the user till the entire page has finished loading.

Insteading of binding events, isn't it faster to call the function using the onclick method in the html providing it with $(this) as a param. This way you will have reference to the context and avoid a DOM traversal

Schmoo @ 11 Jan 2009 3:24 PM

@Felix Nagel: "A much better way is hiding the element by css per default, then showing them by JQuery. If you first show them, they will be visible until the Script is loaded and DOM is ready."

No, no, no! :) Users without javascript will never see it if we do it that way. The content should be there by default, and then hidden/revealed by javascript as required (It says as much in the article, BTW). Besides which, DOM-ready actions are often invisible to the end user, and, at the every least, are lost in the clutter of image loads.

goody @ 14 Jan 2009 10:12 PM

Your explanation of event delegation has been the best I've seen thus far. There's a lot of great stuff here. Thanks!

NickT @ 15 Jan 2009 3:35 PM

Best jQuery tips I've seen yet - made my first project substantially faster.

To thank you (with tongue in cheek):
$(document).ready(function(){
$("*", document.body).each(function(){
$(this).text($(this).text().replace(/less/gi, "fewer")).text($(this).text().replace(/it's/gi, "it is"));
});
});

tilfin @ 23 Jan 2009 1:38 PM

Thank you for your job!

But, I could not understand why #9 is faster.
I guess the following code is wrong.
1. var selectedItem = $('#listItem' + i, $('.myList'));

I think this below is the right code:
// Select each item once
var mylist = $(.myList);
for (i = 0; i < 1000; i++) {
var selectedItem = $('.listItem' + i, myList);
}

As far as I read the constructor source code of jQuery,
you had better write context.find(selector)
If the context of $(selector, context) is already jQuery object.

Chris Keeble @ 30 Jan 2009 5:21 PM

And another thank you from our team - we're in the process of updating a lot of our old websites at the moment, and your article has proven very popular - including with our more seasoned jQuery users! Great work.

dway @ 31 Jan 2009 6:22 PM

in #8, you brake the validation and the normal behaviour of xhtml : you can't give the same ID to 1000 li element, an ID is unique...
To be correct and more simple : use #myList li and remove the class on li...

Akzhan @ 18 Feb 2009 9:32 AM

More robust and fast code for trick #6:

var myList = $('.myList');
var myListItems = [];
for (i = 0; i < 1000; i++) {
myListItems.push('list item # ' + i + '');
}
myList.html(myListItems.join(''));

More robust implementation for trick #24 uses e.preventDefault() method.

$('#id').click(function(e)
{
e.preventDefault();
// do actions
});

Lauri Johnsen @ 23 Feb 2009 9:42 AM

Really awesome article. Thank you!

Vaughn @ 24 Feb 2009 9:24 PM

Thank you for this insightful article. I've referred to it several times.

I am trying to use tip #20, and have run into a snag. I have a form that submits via ajax, and alters an image. I need to compare the before and after widths of the image. I need to know when the image is loaded, because otherwise it's just a matter of timing whether I get the old width or the new. So, I used your .load technique.

I have your tip #20 in the complete function for the ajax.

Pseudocode:
$(".form").submit(function(){
$.ajax ({ ...},
complete: function() {
$("#image).load(function() {
get width, adjust postion;
alert ("done");
});
...etc

The first time I edit and refresh the image, the alert "done" fires once. The second edit, it fires twice, and so on.

I've placed alerts at different places... it's only this one function that is "looping".

What can be done to prevent this? I must be misunderstanding the correct usage of .load() in this context.

Thank you,

Vaughn

ian holmes @ 6 Mar 2009 10:20 AM

First off excellent article - lots of good tips - nice to see them all in one place.

Just wanted to draw your attention to an excellent article from John Resig about packing javascript - smaller is not necessarily better - http://ejohn.org/blog/library-loading-speed/.

His conclusion was that although the packed version is smaller and takes less time to download it performs less well than a minified version due to the fact that the packed version needs to be uncompressed on the client side by a JavaScript decompression algorithm. This uncompression has a tangible cost in load time.

Any thoughts?

Chris @ 9 Mar 2009 12:43 AM

Thank you for a great tutorial, and especially #24. I guess because it's so obvious it never shows up in any of the tutorials / docs I read, yet I've spent 3 hours searching for how to do that.

Thank you!!

Sam Langdon @ 11 Mar 2009 10:47 AM

It is a very good tutorial & the website's looking great. Good work Jon & TVI!

Julien @ 11 Mar 2009 12:20 PM

Amazingly usefull article. I just want to go back to my previous jquery code for optimization now! And thanks for the #23, I was looking for something like that for ages!

Regis @ 13 Mar 2009 12:24 AM

Thank you very much for the best and most inspirational "tips" article I have read about JQuery. I am relatively new to the framework, but I have been reading a lot about it and nothing compared in clarity and relevance. My only problem is that now I feel that I have to go back and re-write a lot of code, in all fairness to the people I am delivering it to...

Sam Langdon @ 17 Mar 2009 4:46 PM

For those of you who use Visual Studio 2008, if you weren't already aware, there's a hotfix that enables intellisense, so you can almost throw the cheat sheet away (maybe just keep it to one side in case VS decides not to play nice :o))

http://blogs.msdn.com/webdevtools/archive/2008/11/07/hotfix-to-enable-vsdoc-js-intellisense-doc-files-is-now-available.aspx

steve m @ 27 Mar 2009 5:57 PM

this is a MUST READ....AWESOME JOB!
I started looking at jQuery just yesterday and this article should be the tutorial on their site.
awesome, awesome.

Nischal Shetty @ 24 Apr 2009 9:35 AM

If you call yourself an intermediate... I'm ashamed to call myself even a beginner :D

Thank you so much for this great article! It's excellent for taking one's jQuery knowledge to the next level :)

anil khandelwal @ 1 May 2009 2:29 PM

excellent article :)

Sanz @ 23 Jun 2009 2:11 PM

Nice list! It will definitely help my code to be more nicely behaved!

But is indexOf not supported in IE? This works in IE6 and 7 - alert("text".indexOf('x'));

Gabriel @ 24 Jun 2009 1:40 PM

suggestion: put a anchor #table_of_contents at end of each post. :)

DG @ 24 Jun 2009 2:21 PM

Really good stuff.Thanks for the article

Blaine @ 9 Jul 2009 4:46 PM

A couple of Issue with #1 and load scripts from Google. If Google is down then you get no scripts, now I know you are going to say Google is never down but they have been down. Another issue is some business will block google( and other sites from employees and therefore your script loading is blocked, if you are do a B2B site this can get you. I will always say it is best to load it from your source, it will not speed up anthying since it will be cached after first use.

Muhsin Meydan @ 1 Aug 2009 3:08 AM

Great hints for web developers!!!

hijik @ 3 Aug 2009 2:08 PM

The site gave me the related information about the development and design for writing an Essay on it.

J @ 4 Aug 2009 4:54 AM

Wonderful tips; I've been using JQuery for some time now and see that I've been doing some things in a bit of a back wards way. Like, instead of using even delegation, I would get some metadata about objects by setting and checking the name, attribute. The JQuery data is new to me and I can see this is all going to be quite useful!

Tom @ 4 Aug 2009 10:50 PM

Say I have the following:
var nav_x1 = $("#item1", divnavrow).parent("a").html("item1 text");
var nav_x3 = $("#item3", divnavrow).parent("a").html("item3 text");
var nav_x5 = $("#item5", divnavrow).parent("a").html("item5 text");

$("#item-actions").append(nav_x1);
$("#item-actions").append(nav_x3);
$("#item-actions").append(nav_x5);

How can I speed up my jquery specifically by combing the 3 appends into a single append. When I try to combine into a single append using a variable to encompass the 3 items, I end up getting an error, [object] gets written out to the page. Any help...?

GT @ 28 Aug 2009 10:27 AM

An absolutely terrific - but reasonably brief - set of guides for us nuffnuffs who haven't the time or resources to learn the whole jQuery structure from 'go' to 'woah'.

As someone who is mildly obsessive about slow scipt execution times, your hints on methods to improvce script efficiency were really very helpful.

Cheerio


GT
Australia

alex @ 30 Aug 2009 1:12 AM

I haven't read all the comments to see if this hasn't been brought up before, but I have input on 2 things.

I think $(document).ready() has much better readability for the programmer. I realise it's more to type though.

I also think instead of returning false to prevent default behaviour, you should use the more semantic method like this

$('a').click( function(e) { e.preventDefault() } );

Otherwise, a great article :)

Shahriar Hyder @ 24 Sep 2009 9:58 AM

Excellent article Jon. Just what I have been looking for. I have also linked to yours from my blog post below where I am trying to collect the most useful and common jQuery code snippets for JavaScript over the web. Here is the title and the link to the jQuery link compilation endeavor:

Ultimate collection of top jQuery tutorials, tips-tricks and techniques to improve performance

http://technosiastic.wordpress.com/2009/09/24/collection-of-top-jquery-tutorials-tips-tricks-techniques-to-improve-performance/

Barry @ 29 Sep 2009 2:00 PM

Jon - excellent post, been referring to it for at least the last 6 months.

I'm not sure if you're aware of it, but a copy of this post (almost identical) has been placed at the following address:
http://www.listelog .com/improve-your-jquery-25-excellent-tips/

Only reason I'm pointing it out is because no credit is given to you (that I can find anyway), and if it were me, I'd like to know about it.

Chema @ 30 Sep 2009 6:00 PM

Congratulations for the post. Excelent job. Thanks for sharing your knowledge

Bruce Lueckenhoff @ 7 Oct 2009 10:38 PM

Thank you for an excellent set of tips.

I found a slight problem with tip number 12, however: If the user clicks a non-TD element of the table, multiple rows, or even the entire table, will be selected.

Compare the behavior if you (intentionally) click on a non-TD element, like a table border. The "bad" method ignores the click. The "recommended" method selects every single TD in the table!

Jones @ 8 Oct 2009 12:26 PM

#7 could have to do with:

"Simple elements without attributes, e.g., "", are created via document.createElement. All other cases are parsed by assigning the string to the .innerHTML property of a div element."
(http://docs.jquery.com/Core/jQuery#htmlownerDocument)

If this is also true for html(), then in the first case, every li is inserted into the DOM via "document.createElement" whereas in the second case the ul with all li children is inserted using innerHTML.

Mark @ 5 Nov 2009 6:43 PM

Great tips... thanks for sharing

Asif @ 6 Nov 2009 3:29 AM

Excellent article no doubt. You just served the web developer community with this great article. I hope to see more articles like this from you!!!

Mrinmoy Mondal @ 14 Nov 2009 7:06 PM

Thanks! Nice document...

Jim @ 18 Nov 2009 7:10 PM

Loads of great advice, tips, and suggestions. Thanks for sharing!

Skidoosh @ 19 Nov 2009 11:31 PM

For anyone who's interested I've published V2 of my jQuery reference from one of the articles featured on here. I don't work there any more so it's not maintained. If you want to have a look at that it's here: http://www.skidoosh.co.uk/jquery/jquery-selectors-and-attribute-selectors-reference-and-examples-v2/ I'll be updating it for 1.3 in a few days.

Sachin Jain @ 4 Dec 2009 1:09 PM

Hey Jon Hobbs-Smith, Good work done man!! this is really very useful...

David Levin @ 5 Dec 2009 1:08 AM

Nice job. Its too bad that document.ready can't tell if everything has been completely loaded (images, external calls, etc...) but its useful nonetheless.

David Masover @ 6 Dec 2009 7:57 AM

One trick I like to use instead of renaming jQuery:

jQuery(function($) {
// my code
});

Quite often, I'll use jQuery for ridiculously quick page modifications, none of which need to happen until the page is loaded. For the rare cases where I have something longer:

(function($) {
// my code
})(jQuery);

Both of these override $ with jQuery, but only inside that code. You can have code from other frameworks outside, you can use noConflict in case jQuery was loaded after those other frameworks, and if you actually need their $ function (not likely), you could always do something like this:

var $p = $; // prototype
(function($) {
$p(some_prototype_query);
$(some_jquery_query);
...
})(jQuery);

I prefer that method because if I'm going to be using $ all the time, and if I'm mostly going to be writing jQuery, I really don't want to be typing $j all the time. These also provide a useful context to write my program -- since it's all inside a function, any variables or functions I create will only be accessible to my code unless I explicitly set them as window (or forget to type var).

Too bad spam has taken over the comments here...

ArcusCox @ 9 Dec 2009 12:46 PM

#12: Learn about event delegation
===========================
e.target does not work in IE

#24: Return 'false' to prevent default behaviour
====================================
there should be written difference between

$('popup').click(function(){
// Launch popup code
return false;
});

and

$('popup').click(function(event){
// Launch popup code
event.preventDefault();
});

fernmicro @ 14 Dec 2009 8:34 PM

concatenating strings is a lot slower than joining an array...

var myList = $('.myList');
var myListItems = '';

for (i = 0; i This is list item ' + i + '';
}

myList.html(myListItems);

// OPTIMIZED

var myList = $('.myList');
var myListItems = [];

for (i = 0; i This is list item ' + i + '');
}

myList.html(myListItems.join());

tak3r @ 27 Feb 2010 5:54 AM

heh, great article man.
I also have a tip for you
At tip #24: 24. Return 'false' to prevent default behaviour, you can easily prevent that "#" thingy by setting a link's href property to href="javascript:void(0)". If you find it that long (i most of the times do) then you can use your href="#" and then with jquery:
$(function(){
$('a[href=#]').attr('href', 'javascript:void');
});

Jones @ 28 Feb 2010 11:35 AM

Good tips, but I think there's a problem with tip 20 and Safari (and maybe Chrome?), it doesn't fire if the image is already loaded (I'm not sure if it's just if the image was already included within the document, or also if it's cached).

Matthew Boston @ 28 Feb 2010 3:10 PM

Great article. I am a very beginner in jQuery, I've only started using it a couple weeks now. One question. You mention (#1) it's better to load through the googleapis but you also mention (#21) to "always use the latest version." Is there a way to have both? I don't see in Google Code a link to the latest jQuery. I know if I'm loading from jQuery's site, I can use http://code.jquery.com/jquery-latest.min.js. Maybe Google code should have a link for jquery/latest/jquery.min.js

Nicholas Tuck @ 17 Apr 2010 7:21 PM

Awesome article man! Stumbled upon this for the first time, and with some of the simple changes, window load() methods etc, I was able to increase the page load speed of our sites dramatically. Intrigued to see the speed difference of the other methods. Jquery has had many versions since, I wonder if they are still as effective or if jquery has hammered many of those out.

Thanks for the great references!