jQuery chaining faster than separate statements? - javascript

Is it faster to write separate calls to the jQuery function, or to use a single chain? If an added explanation of why one is faster than the other, it will be greatly appreciated :-)
An example:
$('#blah_id').niftyjQueryMethod1().niftyjQueryMethod2();
is faster/slower than
$('#blah_id').niftyjQueryMethod1();
$('#blah_id').niftyjQueryMethod2();

In your example, chaining is faster.
// Example 1
$('#blah_id').niftyjQueryMethod1().niftyjQueryMethod2();
// Example 2
$('#blah_id').niftyjQueryMethod1();
$('#blah_id').niftyjQueryMethod2();
In example 1, the call to create the jQuery object ($('#blah_id')) is only made once. In example 2, it is made twice. This means the second call will be slower.
If you don't want to put them all in a chain, you can cache the selection in a variable:
var blah = $('#blah_id');
blah.niftyjQueryMethod1();
blah.niftyjQueryMethod2();
Presuming that the methods don't affect what elements are present in the selection selection (like, for example, parent, find, or filter do) this will be pretty much exactly the same as example 1.

This:
$('#blah_id').niftyjQueryMethod1().niftyjQueryMethod2();
Probably is faster than this:
$('#blah_id').niftyjQueryMethod1(); $('#blah_id').niftyjQueryMethod2();
But not because of the chaining. It's because there's a cost to the selector lookup.
This:
var $blah = $('#blah_id');
$blah.niftyjQueryMethod1();
$blah.niftyjQueryMethod2();
probably has no appreciable difference in speed from the first example.

First one is faster. In the second selector is creating a jQuery object twice. If $('#blah_id') was cached and stored as a variable var $blah = $('#blah_id') and then using in your second selector as $blah and not $('#blah_id') then it would make no real difference.

Yeah, chaining is faster, because the found DOMElement (via the $('#blah_id')) is only directly passed form function to function.
If you seperate them, the DOMElement has to be found again and again and again. Every $("selector") is evil. Try to avoid them as often as possible.
You can even set references to the previosuly found objets:
var myElement = $('#blah_id');
myElement.doSomething();

Related

Should I be caching jQuery selectors in the global namespace? [duplicate]

I have some trouble that comes from my Javascript (JS) codes, since I sometimes need to access the same DOM elements more than once in the same function. Some reasoning is also provided here.
From the point of view of the performance, is it better to create a jQuery object once and then cache it or is it better to create the same jQuery object at will?
Example:
function(){
$('selector XXX').doSomething(); //first call
$('selector XXX').doSomething(); //second call
...
$('selector XXX').doSomething(); // n-th call
}
or
function(){
var obj = $('selector XXX');
obj.doSomething(); //first call
obj.doSomething(); //second call
...
obj.doSomething(); // n-th call
}
I suppose that the answer probably depends by the value of "n", so assume that n is a "small" number (e.g. 3), then a medium number (e.g. 10) and finally a large one (e.g. 30, like if the object is used for comparison in a for cycle).
Thanks in advance.
It is always better to cache the element, if n is greater than 1, cache the element, or chain the operations together (you can do $('#something').something().somethingelse(); for most jQuery operations, since they usually return the wrapped set itself). As an aside, it has become a bit of a standard to name cache variables beginning with a money sign $ so that later in the code it is evident that you are performing an operation on a jQuery set. So you will see a lot of people do var $content = $('#content'); then $content.find('...'); later on.
The second is superior. Most importantly, it is cleaner. In the future, if you want to change your selector, you only need to change it one place. Else you need to change it in N places.
Secondly, it should perform better, although a user would only notice for particularly heavy dom, or if you were invoking that function a lot.
If you look at this question from a different perspective, the correct answer is obvious.
In the first case, you're duplicating the selection logic in every place it appears. If you change the name of the element, you have to change each occurence. This should be reason enough to not do it. Now you have two options - either you cache the element's selector or the element itself. Using the element as an object makes more sense than using the name.
Performance-wise, I think the effect is negligible. Probably you'll be able to find test results for this particular use-case: caching jQuery objects vs always re-selecting them. Performance might become an issue if you have a large DOM and do a lot of lookups, but you need to see for yourself if that's the case.
If you want to see exactly how much memory your objects are taking up, you can use the Chrome Heap Profiler and check there. I don't know if similar tools are available for other browsers and probably the implementations will vary wildly in performance, especially in IE's case, but it may satisfy your curiosity.
IMO, you should use the second variant, storing the result of the selection in an object, no so much as to improve performance but to have as little duplicate logic as possible.
As for caching $(this), I agree with Nick Craver's answer. As he said there, you should also use chaining where possible - cleans up your code and solves your problem.
You should take a look at
http://www.artzstudio.com/2009/04/jquery-performance-rules/
or
http://addyosmani.com/jqprovenperformance/
I almost always prefer to cache the jQuery object but the benefit varies greatly based on exactly what you are using for your selector. If you are using ids then the benefit is far less than if you are using types of selectors. Also, not all selectors are created equally so try to keep that in mind when you write your selectors.
For example:
$('table tr td') is a very poor selector. Try to use context or .find() and it will make a BIG difference.
One thing I like to do is place timers in my code to see just how efficient it is.
var timer = new Date();
// code here
console.log('time to complete: ' + (new Date() - timer));
Most cached objects will be performed in less than 2 milliseconds where as brand new selectors take quite a bit longer because you first have to find the element, and then perform the operation.
In JavaScript, functions are generally short-lived—especially when hosted by a browser. However, a function’s scope might outlive the function. This happens, for example, when you create a closure. If you want to prevent a jQuery object from being referenced for a long time, you can assign null to any variables that reference it when you are done with that variable or use indirection to create your closures. For example:
var createHandler = function (someClosedOverValue) {
return function () {
doSomethingWith(someClosedOverValue);
};
}
var blah = function () {
var myObject = jQuery('blah');
// We want to enable the closure to access 'red' but not keep
// myObject alive, so use a special createHandler for it:
var myClosureWithoutAccessToMyObject = createHandler('red');
doSomethingElseWith(myObject, myClosureWithoutAccessToMyObject);
// After this function returns, and assuming doSomethingElseWith() does
// not itself generate additional references to myObject, myObject
// will no longer have any references and be elligible for garbage
// collection.
}
Because jQuery(selector) might end up having to run expensive algorithms or even walk the DOM tree a bit for complex expressions that can’t be handled by the browser directly, it is better to cache the returned object. Also, as others have mentioned, for code clarity, it is better to cache the returned object to avoid typing the selector multiple times. I.e., DRY code is often easier to maintain than WET code.
However, each jQuery object has some amount of overhead. So storing large arrays of jQuery objects in global variables is probably wasteful—unless if you actually need to operate on large numbers of these objects and still treat them as distinct. In such a situation, you might save memory by caching arrays of the DOM elements directly and using the jQuery(DOMElement) constructor which should basically be free when iterating over them.
Though, as people say, you can only know the best approach for your particular case by benchmarking different approaches. It is hard to predict reality even when theory seems sound ;-).

Caching of javascript variables [duplicate]

I have some trouble that comes from my Javascript (JS) codes, since I sometimes need to access the same DOM elements more than once in the same function. Some reasoning is also provided here.
From the point of view of the performance, is it better to create a jQuery object once and then cache it or is it better to create the same jQuery object at will?
Example:
function(){
$('selector XXX').doSomething(); //first call
$('selector XXX').doSomething(); //second call
...
$('selector XXX').doSomething(); // n-th call
}
or
function(){
var obj = $('selector XXX');
obj.doSomething(); //first call
obj.doSomething(); //second call
...
obj.doSomething(); // n-th call
}
I suppose that the answer probably depends by the value of "n", so assume that n is a "small" number (e.g. 3), then a medium number (e.g. 10) and finally a large one (e.g. 30, like if the object is used for comparison in a for cycle).
Thanks in advance.
It is always better to cache the element, if n is greater than 1, cache the element, or chain the operations together (you can do $('#something').something().somethingelse(); for most jQuery operations, since they usually return the wrapped set itself). As an aside, it has become a bit of a standard to name cache variables beginning with a money sign $ so that later in the code it is evident that you are performing an operation on a jQuery set. So you will see a lot of people do var $content = $('#content'); then $content.find('...'); later on.
The second is superior. Most importantly, it is cleaner. In the future, if you want to change your selector, you only need to change it one place. Else you need to change it in N places.
Secondly, it should perform better, although a user would only notice for particularly heavy dom, or if you were invoking that function a lot.
If you look at this question from a different perspective, the correct answer is obvious.
In the first case, you're duplicating the selection logic in every place it appears. If you change the name of the element, you have to change each occurence. This should be reason enough to not do it. Now you have two options - either you cache the element's selector or the element itself. Using the element as an object makes more sense than using the name.
Performance-wise, I think the effect is negligible. Probably you'll be able to find test results for this particular use-case: caching jQuery objects vs always re-selecting them. Performance might become an issue if you have a large DOM and do a lot of lookups, but you need to see for yourself if that's the case.
If you want to see exactly how much memory your objects are taking up, you can use the Chrome Heap Profiler and check there. I don't know if similar tools are available for other browsers and probably the implementations will vary wildly in performance, especially in IE's case, but it may satisfy your curiosity.
IMO, you should use the second variant, storing the result of the selection in an object, no so much as to improve performance but to have as little duplicate logic as possible.
As for caching $(this), I agree with Nick Craver's answer. As he said there, you should also use chaining where possible - cleans up your code and solves your problem.
You should take a look at
http://www.artzstudio.com/2009/04/jquery-performance-rules/
or
http://addyosmani.com/jqprovenperformance/
I almost always prefer to cache the jQuery object but the benefit varies greatly based on exactly what you are using for your selector. If you are using ids then the benefit is far less than if you are using types of selectors. Also, not all selectors are created equally so try to keep that in mind when you write your selectors.
For example:
$('table tr td') is a very poor selector. Try to use context or .find() and it will make a BIG difference.
One thing I like to do is place timers in my code to see just how efficient it is.
var timer = new Date();
// code here
console.log('time to complete: ' + (new Date() - timer));
Most cached objects will be performed in less than 2 milliseconds where as brand new selectors take quite a bit longer because you first have to find the element, and then perform the operation.
In JavaScript, functions are generally short-lived—especially when hosted by a browser. However, a function’s scope might outlive the function. This happens, for example, when you create a closure. If you want to prevent a jQuery object from being referenced for a long time, you can assign null to any variables that reference it when you are done with that variable or use indirection to create your closures. For example:
var createHandler = function (someClosedOverValue) {
return function () {
doSomethingWith(someClosedOverValue);
};
}
var blah = function () {
var myObject = jQuery('blah');
// We want to enable the closure to access 'red' but not keep
// myObject alive, so use a special createHandler for it:
var myClosureWithoutAccessToMyObject = createHandler('red');
doSomethingElseWith(myObject, myClosureWithoutAccessToMyObject);
// After this function returns, and assuming doSomethingElseWith() does
// not itself generate additional references to myObject, myObject
// will no longer have any references and be elligible for garbage
// collection.
}
Because jQuery(selector) might end up having to run expensive algorithms or even walk the DOM tree a bit for complex expressions that can’t be handled by the browser directly, it is better to cache the returned object. Also, as others have mentioned, for code clarity, it is better to cache the returned object to avoid typing the selector multiple times. I.e., DRY code is often easier to maintain than WET code.
However, each jQuery object has some amount of overhead. So storing large arrays of jQuery objects in global variables is probably wasteful—unless if you actually need to operate on large numbers of these objects and still treat them as distinct. In such a situation, you might save memory by caching arrays of the DOM elements directly and using the jQuery(DOMElement) constructor which should basically be free when iterating over them.
Though, as people say, you can only know the best approach for your particular case by benchmarking different approaches. It is hard to predict reality even when theory seems sound ;-).

Is it more efficient to create a variable for an element or select it each time?

Lets say I'm going to be targeting an element lots of times, which is more efficient?
Example 1:
var el = $("#element");
el.html("foo");
el.html("bar");
Example 2:
$("#element").html("foo");
$("#element").html("bar");
Or is there no difference at all?
Example 1 is more efficient, because you're only calling $() once and reusing the same object for subsequent calls to .html().
It doesn't result in significant numbers, but if you know you are going to be interacting with the same element (or set of elements) then it's obviously redundant to call it each time.
In most cases you can chain methods:
$('#element')
.html('foo')
.html('bar')
This way you gain both performance and readability.
The first example is more efficient; and directly listed in jQuery Performance Rules;
It's Rule 3 - Cache jQuery Objects.
I know there are other answers here already but example 1 is more efficient and you should definitely use it starting now rather than later.
The reason that there is very little difference in performance in your example is because your selector has the highest DOM specificity possible. There is only supposed to be one use of an ID on any HTML page EVER. Even if you physically write the same ID twice, jQuery will only target the first instance.
If you were to do something a little more complex such as this:
$('form').find('input[type="text"]').filter(function(index){
return $(this).css('color') == 'green';
}).somePlugin();
$('form').find('input[type="text"]').filter(function(index){
return $(this).css('color') == 'green';
}).anotherPlugin();
Then it is much more worth it to cache it for better performance like this:
var target = $('form').find('input[type="text"]').filter(function(index){
return $(this).css('color') == 'green';
});
target.somePlugin();
target.anotherPlugin();

To cache or not to cache $(this) in jQuery

Does creating and reusing a reference increase performance appreciably when the selector is $(this)?
I create references for my jQuery selectors when I use the same selector multiple times in the same scope. The following is more efficient
var jSel = $('div.some_class input.some_other_class');
some_function1(jSel);
some_function2(jSel);
than this
some_function1($('div.some_class input.some_other_class'));
some_function2($('div.some_class input.some_other_class'));
But what if the selector is simply $(this) where this is a dom element inside a jQuery method. Should I bother to create a reference to $(this) and reuse the reference or can I create multiple $(this) selectors and expect similar performance?
Is the following
var jSel = $(this);
some_function1(jSel);
some_function2(jSel);
significantly faster than the following?
some_function1($(this));
some_function2($(this));
Is the following significantly faster than the following?
No. It is microscopically faster; in the realms of just a few microseconds.
Does that stop you assigning the result to a variable and using that? No. Using a variable can give more meaning to what this is, and can be easier to type. Plus, if you stopped wanting to operate on $(this), and instead wanted $(this).next(), you have to change it in one place instead of n.
You'll find the jQuery constructor is highly optimized for accepting a single DOM element as a parameter. The following is the exact code that gets executed when you call $(DOMElement) (after the jQuery object has been created, of course):
var match, elem, ret, doc;
// Handle $(""), $(null), or $(undefined)
if ( !selector ) {
return this;
}
// Handle $(DOMElement)
if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;
}
// Handle lots of other param types, but we hit the above one, so we've stopped now...
It all depends on how many calls you make. It's certainly faster to set a variable equal to something that does work than to keep doing the same work, but the difference will be extremely negligible in your sample. If you're doing this in a loop of 5 million, the difference will be less negligible and setting the variable will be faster as it only does the work once and not 5 million times.
In this particular case, if you're really writing functions that expect a jQuery object as a parameter (as in your examples), you could just re-write those functions as jQuery methods. Then you could write:
$(this).some_function1().some_function2();
It's pretty easy to write jQuery methods, at least simple ones. The general (again, simple) form is:
jQuery.fn.some_function = function() {
return this.each(function() {
// stuff you want to do
});
};
this is a reference to the object. Using $(this) takes a bit of time (because of jQuery turning it into an array) but this time is irrelevant IMHO. So the first method should be a bit faster, but actually you won't notice the difference.
http://jsperf.com/jquery-cache-vs-no-chace
Should give you a basic idea of speed difference. In most of the simple cases it probably wouldn't affect your code execution speed noticeably but where JS is a bottleneck every bit helps + it's always a best choice to make good practices a routine!
A lil benchmark:
http://jsperf.com/jquery-this-selector-performance

what is the difference between $("#context .searched") and $(".searched",$("#context"))?

I had that question in mind for a long time.
Theoretically, jQuery core function accepts an optional value that can be a DOM element - $(".searched",$("#context")[0]) - or a jQuery object - $(".searched",$("#context") ) .
I discovered that last question reading that fine article.
But i really cant see the difference between use a context and pass a more complex css expression. If there is no difference in the way it works, is there any perfomance difference?
Thanks
It gets converted to a DOM element (in Sizzle, the context portion) to search in either of your cases, ultimately doing a .find() under the covers.
If you're concerned about performance (why not be as fast as possible?), you should use this instead:
$("#context .searched")
This version gets converted back into a jQuery object:
$("#context")[0]
So it's a bit slower on the jquery side, since it has to be wrapped in a jquery object before the .find() call, that performance difference is very minimal, but it's the only difference so I'm noting it :)
The major difference would be that $(".searched", context); can take a variable as a context as well. It is effectively doing $(context).find('.searched'); under the hood, and I think the second version is more readable anyway, so I usually use that.
The use for this situation would be something like this:
$.fn.highlightSearch = function() {
return this.each(function() {
$('.searched', this).addClass('highlighted');
// the commented line performs the same thing:
// $(this).find('.searched').addClass('highlighted');
});
};
$('#context').highlightSearch();
$('.somethingElse').highlightSearch();
Notice that in this case, you can't simply append the new selector on the end of the original.
If you have no other reason to hold a copy of $('#context'), then using $('#context .searched') is going to be quicker, and simpler. However, if you already had $('#context') stored in a variable, its better to use .find(select) or the $(selector, context) form to search for your contained elements.
Readability: a CSS selector like $("#context .searched") is far more readable than the other.

Categories