Is there a cost to jQuerying an existing jQuery object?

303 views Asked by At

I'm wondering whether lazily doing $( something ) without first checking whether something is already a jQuery instance has any performance downsides?

The use case I'm thinking of is a function like the following:

function foo( element ){
  var $element = $( element );
  // do something with $element...
}

If you pass a jQuery instance to that function, are you re-wrapping a jQuery instance with another jQuery instance? And does that have any performance implications (say, over many iterations)?

foo( $( "#somediv" ) );

Looking at the source code (v 2.1.4 as of this question), we see jQuery.fn.init checking the selector that's passed to it, and if it's not a string, a DOM element or a function, then we just pass it through jQuery.makeArray and return the result.

So there doesn't appear to be any explicit checking within the jQuery "constructor" that short-circuits if the selector is already a jQuery instance. But does it really matter?

makeArray uses merge and/or push, so there's a bit of extra processing, but is it significant?

1

There are 1 answers

7
Tom Auger On BEST ANSWER

All right, since I seem to never be able to walk away from a Yak that needs shaving, here's the JSPerf test, which seems to suggest that checking and short-circuiting instead of (accidentally) re-wrapping a jQuery instance can improve performance by up to 30%. In my books, that's significant enough to warrant the uglier code.

Here are the two tests:

function noCheck(element) {
  var $element = $(element);

  $element.css("color", "red");
}

noCheck($("#somediv"));

function shortCircuit(element) {
  var $element = element instanceof jQuery ? element : $(element);

  $element.css("color", "red");
}

shortCircuit($("#somediv"));

According to JSPerf, noCheck performs 30% slower than shortCircuit

Play around with this code in JSFiddle.

I'm not going to accept my answer for a while to encourage additional perspectives / tests, etc.