views:

93

answers:

3

Imagine this simplified markup:

<div id="header">
   <!-- Other things.... -->
   <div id="detail">

   </div>
</div>

and assume you already have this code:

var $hdr = $("#header");

Is there any speed difference for jQuery to lookup "detail" this way:

var $detail = $("#detail", $hdr);

vs

var $detail = $("#detail");

Since detail is being looked up by ID?

+6  A: 

No, you don't have to do that. Since id is unique in a document no need to add any other optimization.

I would go with

var $detail = $("#detail");
rahul
and I have seen reliable documentation with tests to show it is slower with context when scope is included, just cannot find the link at the moment.
Mark Schultheiss
+6  A: 

No. Passing a context will actually make it slower. The relevant source code from jQuery is given below with an explanation.

This code basically says:

  1. If (the selector is an HTML string or an id, AND (either it's specifically HTML or no context is given)) 1.a Then do some stuff like calling document.getElementById()
  2. Otherwise evaluate the context, and then run the selector

And here's the stripped out source..

init: function( selector, context ) {
    ...
    if ( typeof selector === "string" ) {
        ...
        // This gets ignored because we passed a context
        // document.getElementById() isn't called directly
        if ( match && (match[1] || !context) ) {
            ...
            } else {
                elem = document.getElementById( match[2] );
                ...
            }
        ...
        // Either this gets executed if a jQuery wrapped context was passed
        } else if ( !context || context.jquery ) {
            return (context || rootjQuery).find( selector );
        }
        // Or this gets executed, if a simple selector was passed as context
        } else {
            return jQuery( context ).find( selector );
        }
    ...
}

match is the resulting array of a regular expression to find out if the selector is either an HTML string, or an id expression. If it's an HTML string, then match[1] will be populated. If it's an id (#someId), then match[2] will be populated.

Anurag
+1, also without even looking at the source it stands to reason that it'll be slower if ID selectors are even remotely well-optimized, as adding a context adds a second condition to check.
eyelidlessness
Not sure if adding a simple condition to ignore context in case of ID selectors will have any noticeable effects. One reason to have it like this, I would imagine, is too provide access to elements that have a duplicate ID. I know it's not good and illegal, and browser dependent and stuff, but `document.getElementById` always returns the first match. Using `$('#id', someContext)` however will allow you to get to a second, third, fourth, .. element with the exact same id.
Anurag
+2  A: 

The answer lies in how the IDs are stored. Assigned IDs are kept in a hash-like data structure. If searching for a fully qualified ID (not [id*="foo"]) then the locating time required should be fastest without any modifiers because it is a direct hash lookup.

dhackner