Reputation: 26281
Consider the following two sections of script. The first is one line shorter and uses one less variable $t
, however, converts this
into a jQuery object one additional time.
From a performance (not readability) perspective, is one better than the other?
If the first is better, is there a point where one would want to use the second such as I need to convert this
into a jQuery object one hundred times? Are there any rules of thumb when this transition should be made?
$(".click").click(function(){
$('body').data('link',$(this));
$("#dialog").data('id',$('#id').val()).data('status',$(this).text()).dialog("open");
});
$(".click").click(function(){
var $t=$(this);
$('body').data('link',$t);
$("#dialog").data('id',$('#id').val()).data('status',$t.text()).dialog("open");
});
Upvotes: 0
Views: 47
Reputation: 1063
Obviously, the second example is more efficient from a performance perspective.
Imagine you are a builder and you are on a ladder fixing up a broken ceiling. Your first example is like you have the tools you need in you toolbox down on the floor. The second example is like you have tools right in your tool belt and you don't have to climb down the ladder to get the tools and climb up again.
Upvotes: 0
Reputation: 1074545
It's probably faster, as $()
does a bit of work to figure out what you've given it. It's extremely unlikely to matter, when you're giving $()
a DOM element. If you're not in a tight loop, it's not important. Handling a click
isn't exactly a performance-critical bit of code.
Where you get into differences is when you're repeatedly querying the DOM, e.g.:
$(".foo[data-nifty]").doThis();
$(".foo[data-nifty]").doThat();
$(".foo[data-nifty]").doTheOther();
There, you're forcing repeated searches of the DOM for all elements with class foo
and a data-nifty
attribute for no good reason. Now, unless that's in a loop, it probably doesn't matter either, but that's the kind of place you should be looking out for. If all three of the methods are chainable, write a chain, or use a temporary variable.
In general, write readable code, test early and often, and when you see real-world performance issues, deal with them.
The converse is also something to look for:
$(".foo").click(function() {
var $t = $(this);
$t.doThis();
$t.doThat();
$t.find(".something").not(".hooked").addClass("hooked").on("click", function() {
// Do something here without using `$t`...
});
});
There, we're looking within the clicked .foo
element for any .something
that doesn't have .hooked
and, if found, adding a click handler to it. (This is obviously quite contrived; we'd use event delegation instead. But assume it's something that we would really write.)
In theory, if there were any new .something
s hooked, then their event handler is retained, and since it's a closure over the context of that click, the $t
variable is kept in memory, meaning that whatever the $t
variable refers to is also kept in memory. And so we could end up using more memory than we would ideally want to. (Since the set of DOM elements in $t
isn't something we need to keep in $t
.)
In practice, modern engines can and sometimes do "optimize" closures, releasing variables that theory says they need to keep, if they can prove to themselves they can do it without causing side-effects. But relying on that when you don't need to is not ideal. In the above, you could add $t = undefined;
or $t = null;
at the end to release the jQuery set it refers to. The context of the call and the $t
variable may still be kept (barring JavaScript engine optimizations), but at least the jQuery set $t
used to refer to isn't.
Upvotes: 3