Is it recommended that, when I need to access the result of a jQuery selector more than once in the scope of a function, that I run the selector once and assign it to a local variable?
Forgive my trite example here, but i think it illustrates the question.
So, will this code perform faster:
var execute = function(){
var element = $('.myElement');
element.css('color','green');
element.attr('title','My Element');
element.click(function(){
console.log('clicked');
});
}
than this code:
var execute = function(){
$('.myElement').css('color','green');
$('.myElement').attr('title','My Element');
$('.myElement').click(function(){
console.log('clicked');
});
}
If there is no difference, can anyone explain why? Does jQuery cache elements after selecting them so subsequent selectors don't have to bother searching the dom again?
Reusing the selector reference, your first case, is definitely faster. Here's a test I made as proof:
http://jsperf.com/caching-jquery-selectors
The latter case, redefining your selectors, is reported as ~35% slower.
Don't forget this one:
var execute = function(){
$('.myElement')
.css('color','green')
.attr('title','My Element')
.click(function(){
console.log('clicked');
});
}
Storing the reference in a local variable will be faster than running the selection code each time. It's simply a matter of not having to execute ANY code to find the appropriate element(s) when you store it in a variable. My rule of thumb is to store the results of the jQuery lookup in a variable if I'm going to use it more than once.
Another option here is to use an each
instead of repeating the selector, and it's associated work, time and time again
var execute = function(){
$('.myElement').each(function() {
var elem = $(this);
elem.css('color','green');
elem.attr('title','My Element');
elem.click(function(){
console.log('clicked');
});
});
}
You're actually forgetting the truly cached approach.
The thing with jQuery is that the initial lookup: $('.selector')
is expensive. But after that, chaining your actions onto it, or assigning it to a variable and executing your actions on the variable don't matter that much. The main performance gain you can get is caching the element even further, and not assigning the jQuery selector each iteration of your function call.
var element = $('.myElement');
var execute = function(){
element.css('color','green');
element.attr('title','My Element');
element.click(function(){
console.log('clicked');
});
}
This approach is almost twice as fast as the fastest version from the other approaches suggested.
See http://jsperf.com/caching-jquery-selectors/17
Note: If your DOM changes during it's lifetime, you can update the element
variable with the a fresh selection of elements.