Minimizing jQuery instance vs creating more instances
Asked Answered
M

3

9

I started a series of posts on javascript / jQuery optimization and stumbled upon this interesting result.

Why is it that minimizing jQuery objects (by searching from a cached jQuery collection) can be slower then creating more instances of jQuery objects?

I was stunned to see the results of a test i prepared. I always thought that minimizing creating $ instances are slower.

This is what i am used to write, as i cache the parent (i call it "appRoot").

var appRoot = $("#appRoot");
    appRoot.find(".element1").css("color","red");
    appRoot.find(".element2").css("color","blue");

vs

    $(".element1").css("color","red");
    $(".element2").css("color","blue");

See the test results (slightly different scenario). jsperf minimize-jquery-object-creation it turns out that the cached snippet is slower then the uncached snippet.

I am trying to understand why?

Manstopper answered 12/7, 2011 at 20:22 Comment(2)
This is why code profiling is so important.Burn
Maybe the jquery .find() is slower then the DOM searching ?Cowman
M
2

You need to consider that your test contains less than 10 divs or other html elements. The reason to write code like in the first example is to make the selector faster, but with the cost of additional method calls. Normaly the selector should be the more expensive of the two by far so the the gain would outweight the loss but with a DOM this small the selector will be very cheap no matter how you write it.

People often make the misstake of not remembering that a more complex and large DOM will change the bottlenecks of the code. I think jsperf should have some kind of warning about this.

Muniz answered 12/7, 2011 at 20:43 Comment(0)
L
3

I think the find() call is what's slowing things down.

The only reason to cache a jQuery object is if you're going to be referencing or manipulating it multiple times. If you're just setting a CSS property and that property's not going to be changed by for the life of the rendered page, then there's no reason to define a cache variable.

Lipstick answered 12/7, 2011 at 20:28 Comment(7)
Interesting point, we will need to change the test, any idea how to get down to the bottom of this?Manstopper
It appears this is correct. .find() filters through the elements checking to see if the children matching the selector while $('.className') uses the native document.getElementsByClassName if it exists.Toulon
so $(".element1",appRoot) will be fastest?Manstopper
@Manstopper It appears so, yes. If sizzle finds a class and a context is passed, context.getElementsByClassName is used.Toulon
@adardesign: $(".element1",appRoot) is ultimately identical to appRoot.find(".element1");Vedic
See jsperf.com/minimize-jquery-object-creation/11 which has a little different results, complicating this a little more :)Manstopper
...here it is in the source. It just gets flipped around to use .find().Vedic
C
2

I think it is because the in "more jquery objects created", jQuery can make a direct use of the recent API

document.getElementsByClassName("classvalue")

in the other case with "less jquery" you have to always verify that the element found are under #appRoot which takes more time.

Here is another test using document as appRoot which seems to close the gap a little on the second run: http://jsperf.com/minimize-jquery-object-creation/6

Chaparro answered 12/7, 2011 at 20:36 Comment(1)
I wondered the same thing, except that it could use appRoot.getElementsByClassName("element1") to still use that native function, but just return children of appRoot.Underwrite
M
2

You need to consider that your test contains less than 10 divs or other html elements. The reason to write code like in the first example is to make the selector faster, but with the cost of additional method calls. Normaly the selector should be the more expensive of the two by far so the the gain would outweight the loss but with a DOM this small the selector will be very cheap no matter how you write it.

People often make the misstake of not remembering that a more complex and large DOM will change the bottlenecks of the code. I think jsperf should have some kind of warning about this.

Muniz answered 12/7, 2011 at 20:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.