21

I was reading this article by Brandon Aaron here, about how jquery context may help. So i thought of doing a test of my own. So this is what I did.

  1. Created a DIV with id="context" and nested DIV with id="holder" in "#context" created earlier.

  2. Created a nested DIVs of depth 18 and append <div id="context"><div id="holder"></div></div> to it resulting in 20 nested DIVs

  3. Now I tested time taken to access "#holder" via the following selectors:
    a. $("#holder") // no context
    b. $("#holder", "#context") // with "#context" selector string
    c. $("#holder", $("#context")) // sending jquery object each time with selector "#context"
    d. $("#holder", $context) // where, var $context = $("#context"). Caching jquery obj
    Each of the cases where accessed X = 1000 times and start and end time difference was noted. I found that time taken for:
    case(a) was the least consistent 28-32msec [jquery-1.3.2]
    case(b)+(c) had the highest times 60-65 msec & 70-75 msec respectively
    case(d) had 40-50msec with 1 or 2 spiked values.

Is this type of basic check valid? You can play with the JS code here at JSBIN. [Do let me know If I can improve this test some how]
If YES, then how does this 'context' really help?


#NOTE: also replace the jquery-1.3.2 with jquery-1.4.2 in jsbin edit mode and you'll be surprised to see the numbers bump up :P

1
  • that's a good finding. As Coronus said, for #id selectors you shouldn't pass a context. But here lies the gap between native and jQuery. With duplicate id's, using document.getElementById() will always get the first match. $('#dupeId', '<selector>') can make the second or more elements with a duplicate id accessible. Commented Mar 11, 2010 at 1:36

6 Answers 6

31

Context really helps when you have a much larger DOM that you are searching through. Searching for IDs is already very fast and context doesn't really help that much in that case. Where context can really make a difference is when you are selecting by tag name or class.

Try testing like this: http://jsbin.com/aciji4/4

you can really see the timing get better for context when you bump up number of items in the DOM like this: http://jsbin.com/aciji4/6

Sign up to request clarification or add additional context in comments.

1 Comment

Yes it does makes sense. select by id itself highly optimized, its the other forms of a 'selector' that are optimized by providing a context. BTW thanks for the snippet updates, it really helped.
4

It would make sense that it would take longer to use a context (vs. using a selector alone) since internally, the context uses the .find() method, so in essence, all you are really doing is

$('#context').find('#holder');

I mainly see it as an easier way to identify elements in events and iterators where the context changes because

$('.holder', this)

is prettier than

$(this).find('.holder')

1 Comment

Good observation. For ID's, as longer as they are unique on a page (which they should be, but may not be), passing a context will slow things down.
3

The #ID selector relies on the browser native document.getElementById. It's going to be fast no matter what.

Try a selector like div.class[attribute=value] with and without a context. For example*, you could select the "Related" question links to the right with this selector:

// Selects anchor elements with href's beginning with /questions/
$('a[href^=/questions/]')

But, it's faster to limit how many anchor elements the selector engine has to iterate over, evaluating that relatively expensive text matching:

$('a[href^=/questions/]', '.related')

* And ignoring the obviously easier .question-hyperlink class on those links, for the sake of discussion.

Comments

3

For what it's worth, $context = $("#context") is still using a jQuery object, which then has to be converted to a DOM object.

If you use $context = $("#context")[0] you'll find that it runs just as fast as the first test.

Comments

1

I've taken the JSBin code and put it into a jsPerf Test

$context.find('.holder') is twice as fast as its closest competitor, $('.holder', $context) and that is a good ten times faster than any other selector being used.

In conclusion, cache your selectors and use .find() for maximum performance

Comments

1

Be careful before you going to refactor your code. As in the #NOTE written, jQuery since 1.4 works quite different way. The latest version may contain even more optimizations.

I modified the jsbin code above to have the recent jQuery, and added some additional cases as well. You will see, now only those three (2,3,6) cases got performance penalty which creates one more jQuery object per round. Rest runs in quite same time.

You can find the modified version here: http://jsbin.com/aciji4/63/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.