Not all jQuery selectors are created equal 2

Posted by Jack Hsu Thu, 24 Dec 2009 14:36:00 GMT

The good thing about JavaScript libraries such as jQuery is that developers can focus on functionality without having to worry too much about cross-browser compatibility. However, often times it is still very useful to know why happens behind the abstractions.

The most used feature in jQuery is the CSS selector. Instead of selecting elements using pure DOM (e.g. document.getElementById(‘myId’)), you’re able to use jQuery’s CSS selector (e.g. $(‘#myId’)). This makes life much, much easier.

There are cases, however, where not knowing what happens behind the scenes can lead to poor implementations, causing big performance hits. One such case is the class selector (e.g. $(‘.someClass’)).

The reason why class selector is slow is because it has to go through the entire DOM to find those elements. Of course, some browsers like Firefox 3+ has native support for document.getElementsByClassName. And as John Resig analyzed, the native method is much faster than the next fastest implementation (XPath). But if you want your applications to run as fast as possible on as many browsers as possible, it’s better to avoid the class selector all-together (at least for now).

What you can do instead is to use the next fastest selector (behind ID selector), the tag name selector.

So instead of doing $(‘.someClass’), use $(‘div.someClass’), or whichever HTML tag name you want to use. This selector is faster because instead of checking the entire DOM, now it only needs to check against elements with that particular tag name. That is, it first does a document.getElementsByTagName(‘div’), then iterates through that list.

Or why not make it even faster by specifying an ancestor element by its ID? (e.g. $(‘#ancestor div.someClass’))

The thing to keep in mind is, no matter what abstractions come about, it’s still a very good idea to understand what happens underneath the hood. :)

JavaScript: Optimizing loops

Posted by Jack Hsu Wed, 23 Dec 2009 20:35:00 GMT

When looping through very large arrays, you may find this tip useful: it’s much fast to use a while loop to iterate through an array than a for loop.

For example, if you take this code:

var myArray = new Array(10000);
for (var i=0; i<myArray.length; i++) {
    myArray[i] = i;
}

You can make it run faster by using a while loop instead.

var myArray = new Array(10000);
var n = myArray.length;
while (n--) {
    myArray[n] = n;
}

This works because n-- will return the value of n and then decrement it. So when it approaches index zero, it’ll coerce 1 to true, then decrement n before the line myArray[n] = n;.

Of course, this while-loop is looping backwards, so if the order of iteration does matter then you can’t use this method. You could however, still optimize the first example by first assigning myArray.length to a variable, then using that in the for-loop’s exit condition. This will make it run slightly faster (depending on which browser you’re using) because it avoids a property lookup at every loop iteration.

var myArray = new Array(10000);
var n = myArray.length;
for (var i=0; i<n; i++) {
    myArray[i] = i;
}