Pregunta

Tengo grandes variaciones en el rendimiento dependiendo de cómo expreso mis selectores. Por ejemplo, observe estos 2 selectores, que seleccionan exactamente los mismos elementos:

A) someTableRow.find("td.someColumnClass").find("span.editMode").find("input")
B) someTableRow.find("td.someColumnClass span.editMode input")

Esperaría que B) sea más rápido ya que solo hay 1 llamada, pero de hecho estoy encontrando que A) se ejecuta alrededor de 8 veces más rápido. No tengo idea de por qué, ¿alguien tiene alguna idea? Gracias

¿Fue útil?

Solución

Suponiendo que está utilizando al menos jQuery 1.3 (es decir, con la adición de Sizzle), el rendimiento que está viendo se debe al cambio en el que se atraviesa el DOM. Desde aquí :

  

Hasta e incluyendo jQuery 1.2.6 el   El motor del selector funcionaba en una `` arriba hacia abajo ''   (o "de izquierda a derecha"). jQuery   1.3.x (es decir, Sizzle , que jQuery incorpora) introdujo un "abajo hacia arriba" ; (o   " de derecha a izquierda ") enfoque de consulta   el DOM.

En su segundo ejemplo ( " td.someColumnClass span.editMode input " ), Sizzle efectivamente hace esto:

  1. obtener todos los elementos input dentro de someTableRow
  2. para cada elemento input encontrado, atraviese su árbol ancestro para elementos span con class = " editMode " . Elimine los elementos input que no tienen estos antepasados ??
  3. para cada elemento span.editMode encontrado, recorra su árbol ancestro para elementos td con class = " someColumnClass " . Elimine los elementos input que no tienen estos antepasados ??

Sin embargo, en su primer ejemplo, está calificando cada paso explícitamente con cada llamada a find () , definiendo un contexto y atravesando abajo desde allí. Estás aplicando la "arriba-abajo" enfoque. Es equivalente a pasar a un contexto en cada paso, que es generalmente considerado un refuerzo de rendimiento :

$('input', $('span.editMode', $('td.someColumnClass', someTableRow)))

Otros consejos

Porque estás reduciendo el contexto para la búsqueda.

En el caso B, tiene que buscar a través de cada elemento DOM para ver si cumple con los criterios.

En el caso A, se puede decidir rápidamente ignorar cualquier cosa que no sea "td.someColumnClass", entonces puede tomar ese subconjunto del DOM e ignorar cualquier cosa que no esté en "span.editMode". Por lo tanto, tiene un conjunto mucho más pequeño de elementos para buscar y encontrar " input " s ahora.

A es más llamadas, pero más simple. B es una llamada, pero más compleja. En este caso, la complejidad de la llamada supera en gran medida la cantidad de llamadas.

La forma en que JQuery maneja los selctores es un poco diferente al CSS en mi experiencia.

Reducir el contexto a la búsqueda es la clave como señaló Josh.

Encuentro que usar los dos selectores de parámetros es realmente rápido

¿Cómo se compara esto en cuanto a velocidad?

No necesita todos los vars aquí, es solo para aclarar lo que estoy haciendo.

var columnClasses = $('.someColumnClass');
var tableCell = $('td', columnclasses);
var editMode = $('.editmode', tableCell);
var spanInside = $('span', editMode);
var inputFinally = $('input', spanInside);

Bondad,

Dan

Investigué un poco sobre jQuery Selector Performance. Un gran problema son las búsquedas por nombre de clase en Internet Explorer. IE no admite getElementsByClassName, por lo tanto, jQuery y otros marcos '' reimplement '' en JavaScript iterando a través de todos los elementos DOM. Consulte el siguiente blog de análisis sobre jQuery Selector Performance

Aquí hay un artículo realmente interesante sobre el rendimiento del selector: http: // blogs .atlassian.com / developer / 2009/08 / jquery_bondage.html

En ella, el autor muestra una "vinculación" Extensión jQuery que muestra cuántas veces se evalúa la función.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top