Presuming you are using at least jQuery 1.3 (i.e. with the addition of Sizzle), the performance you are seeing is due to the change in which the DOM is traversed. From here:
Up to and including jQuery 1.2.6 the
selector engine worked in a "top down"
(or "left to right") manner. jQuery
1.3.x (ie, Sizzle, which jQuery embeds) introduced a "bottom up" (or
"right to left") approach to querying
the DOM.
In your second example ("td.someColumnClass span.editMode input"
), Sizzle effectively does this:
- get all
input
elements inside someTableRow
- for each
input
element found, traverse its ancestor tree for span
elements with class="editMode"
. Remove input
elements that don't have these ancestors
- for each
span.editMode
element found, traverse its ancestor tree for td
elements with class="someColumnClass"
. Remove input
elements that don't have these ancestors
In your first example however, your are qualifying each step explicitly with each call to find()
, defining a context and traversing down from there. You are enforcing the "top-down" approach. It is equivalent to passing in a context at each step, which is generally considered a performance booster:
$('input', $('span.editMode', $('td.someColumnClass', someTableRow)))