In my opinion, one of the best jQuery performance tips is to minimize your use of jQuery. That is, find a balance between using jQuery and plain ol’ JavaScript, and a good place to start is with ‘this‘. Many developers use $(this) exclusively as their hammer inside callbacks and forget about this, but the difference is distinct:
When inside a jQuery method’s anonymous callback function, this is a reference to the current DOM element. $(this) turns this into a jQuery object and exposes jQuery’s methods. A jQuery object is nothing more than a beefed-up array of DOM elements.
Digging a little deeper
As you begin to nest functions the context of this changes:
<a href="#"><span>Hello World</span></a> $("a").click(function(event){ var self = this; $(this).find("span").each(function(){ console.log(self, this); }); event.preventDefault(); });
In this example I save this to the variable “self” so it can be referenced inside the each() loop. Otherwise it’s impossible to reference this as the anchor element inside the loop, because this is now the “span” DOM element.
Depending on what you’re doing, using this is sometimes easier and always faster than $(this). I’m not talking about scraping jQuery altogether, but rather recognizing that a lot of DOM interaction (especially the simple stuff) can just as easily be done in vanilla JS using this; you are not required to use the jQuery API. Example:
<a href="test.htm">Test</a> $("a").click(function(){ var href = this.href; // the href property can be accessed through 'this' });
A more verbose example demonstrating the uses of this and $(this) to get an anchor’s href value. These statements are equivalent:
$("a").click(function(){ var href; href = this.href; // sets "href" to "test.htm" href = $(this).attr("href"); // also sets "href" to "test.htm" after going through the jQuery attr() method. // because $(this) is really just a beefed-up array, we can pull off the DOM element using array notation. href = $(this)[0].href; });
The point here is that turning this into a jQuery object and using the attr() method is more time consuming than just referencing the “href” property of this. When manipulation is involved the performance implications are even greater.
Benchmarks
To quantify my claims, I wrote a profiling function that calculates the execution time of looping a block of code 50,000 times:
var profile = function(label, code, iterations){ var start, total, i = iterations = iterations || 50000; start = (new Date).getTime(); while(i--){ code.call(); } total = (new Date).getTime()-start; console.log(label + ': %d ms (looping %l times)', total, iterations); }
I then setup a page with one anchor element and a click event to call the profile function:
$("a").click(function(event){ // save $(this) and 'this' - their reference change inside the profile function! var $this = $(this), self = this; console.log('Accessing the href attribute of a link:'); profile('$this.attr("href")', function(){ href = $this.attr("href"); }); profile('self.href', function(){ href = self.href; }); profile('self.getAttribute("href")', function(){ href = self.getAttribute("href"); }); event.preventDefault(); });
Update 1/7/2010: JAlpino pointed out in the comments that the getAttribute(“href”) method can be called on this to gain an additional +/- 350ms, as opposed to using this.property syntax. I’ve added this method to the benchmarks & results. Thanks, JAlpino!
The results using jQuery 1.3.2 and 1.4a2 respectively on Firefox 3.5.6:


self.href provides a 270% improvement when using jQuery 1.3.2 and a 200% improvement when using 1.4a2. Using the getAttribute() method provides an additional 72% boost over self.href! Keep in mind that in ‘the jQuery way’ these numbers do not include the time it takes to convert this into a jQuery object; we’re caching that outside the profile function, and thus are only benchmarking the performance of the attr() method. How does this perform over $(this) when used for manipulation? I ran the profiler again, this time changing the link color to red:
profile('the jQuery way', function(){ $this.css("color", "#ff0000"); }); profile('vanilla javascript', function(){ self.style.color = "#ff0000"; });


We’re looking at a 632% improvement under jQuery 1.3.2 and a 206% improvement under 1.4a2. Pretty good for changing one line of code.
Putting this into context
You can pass an optional second argument called context to the jQuery object constructor, which gives jQuery a starting point when searching the DOM for your selector. The context can be either a DOM element or jQuery object, but ideally should be a DOM element – like this! Given the markup below and what we know about this and $(this), the “span” child of the anchor can be found four ways:
<a href="testing.htm"><span>test link</span></a> $("a").click(function(){ // these statements accomplish the same thing $(this).find("span"); $("span", this); $("span", $(this)); $("span", $(this)[0]); });
The first example turns this into a jQuery object and calls the find() method. The second example looks for a span element using this – a reference to the anchor DOM element – as the starting point. Because the context argument in the third example is a jQuery object, jQuery internally converts the statement to $(this).find(“span”), which is equivalent to the first example. We’re about to see that this is the slowest method, however, probably due to the overhead in converting the context to a find(). The fourth method is equivalent to $(“span”, this), except that this is first converted into a jQuery object, and then the DOM node is pulled off the array.
My original plan going into this blog post was to show you the performance benefits you can gain when using this as the context argument to the jQuery constructor as opposed to $(this), but my results show otherwise. Note that I ran these tests 20,000 times instead of 50,000 (Firefox got cranky):
$("a").click(function(event){ // cache $(this) and 'this' var $this = $(this), self = this; profile(' $this.find() ', function(){ $this.find("span"); }, 20000); profile(' $("span", this) ', function(){ $("span", self); }, 20000); profile(' $("span", $this) ', function(){ $("span", $this); }, 20000); profile(' $("span", $this[0]) ', function(){ $("span", $this[0]); }, 20000); event.preventDefault(); });


When using jQuery 1.3.2, $(this).find() was 4% faster than providing a DOM element as the context and 53% faster than using a jQuery object – pretty negligible. 1.4a2 shipped with some nice speed improvements; the performance of all four are about the same, but $(this).find() is still a bit faster.
To reiterate, I’m not saying skip jQuery and code everything in plain JS because it’ll make your site faster. The speed improvements I pointed out are trivial but can absolutely add up, especially in larger applications. There are a number of good reasons to use $(this) over this; cross-browser compatibility is one, the extreme ease of use another, but just be aware this exists.
Click here to see the code and run these benchmarks yourself.
Related posts: