javascript - examples - jquery selector id contains
Buenas formas de mejorar el rendimiento del selector jQuery? (12)
Estoy buscando la forma de mejorar el rendimiento del selector de una llamada jQuery. Específicamente cosas como esta:
Es $("div.myclass")
más rápido que $(".myclass")
Creo que podría ser, pero no sé si jQuery es lo suficientemente inteligente como para limitar la búsqueda por nombre de etiqueta primero, etc. ¿Alguien tiene alguna idea sobre cómo formular una cadena de selector jQuery para obtener el mejor rendimiento?
A continuación se detalla cómo aumentar el rendimiento de sus selectores de jQuery:
- Seleccione por #id siempre que sea posible ( resultados de la prueba de rendimiento ~ 250 más rápido)
- Especifique el alcance de sus selecciones (
$(''.select'', this)
)
Añadiré una nota que dice que en el 99% de las aplicaciones web, incluso en las aplicaciones pesadas de ajax, la velocidad de conexión y la respuesta del servidor web impulsarán el rendimiento de su aplicación en lugar del javascript. No digo que deba escribir código intencionalmente lento o que, por lo general, estar al tanto de lo que las cosas probablemente sean más rápidas que otras no sea bueno.
Pero me pregunto si estás tratando de resolver un problema que aún no existe, o incluso si estás optimizando para algo que podría cambiar en el futuro cercano (por ejemplo, si más personas comienzan a usar un navegador que admita getElementsByClassName()
función mencionada anteriormente), lo que hace que su código optimizado realmente se ejecute más lento.
Como Reid dijo anteriormente, jQuery funciona de abajo hacia arriba. A pesar de que
eso significa que
$(''#foo bar div'')
es mucho más lento que$(''bar div #foo'')
Ese no es el punto. Si tuviera #foo
, no pondría nada en el selector, ya que los ID deben ser únicos.
La cuestión es:
- si está subseleccionando algo de un elemento con un ID, seleccione el primero y luego use
.find
,.children
, etc. .:$(''#foo'').find(''div'')
- la parte más a la izquierda (la primera) del selector puede ser una escalada menos eficiente a la última parte (la última) que debería ser la más eficiente, lo que significa que si no tiene una identificación, asegúrese de estar buscando
$(''div.common[slow*=Search] input.rare'')
lugar de$(''div.rare input.common[name*=slowSearch]'')
- ya que esto no siempre es aplicable, asegúrese de forzar el orden selector al dividir en consecuencia.
Considere usar la biblioteca Sequentially de Oliver Steele para llamar a los métodos a lo largo del tiempo en lugar de hacerlo a la vez.
http://osteele.com/sources/javascript/sequentially/
El método "eventualmente" lo ayuda a llamar a un método después de un cierto período de tiempo desde su llamada inicial. El método "secuencialmente" le permite poner en cola varias tareas durante un período de tiempo.
¡Muy útil!
Creo que seleccionar primero por ID es siempre más rápido:
$("#myform th").css("color","red");
debería ser más rápido que
$("th").css("color","red");
Sin embargo, me pregunto cuánto ayuda el encadenamiento al comenzar con la ID. Es esto
$("#myform").find("th").css("color","red")
.end().find("td").css("color","blue");
más rápido que esto?
$("#myform th").css("color","red");
$("#myform td").css("color","blue");
En algunos casos, puede acelerar una consulta al limitar su contexto. Si tiene una referencia de elemento, puede pasarla como el segundo argumento para limitar el alcance de la consulta:
$(".myclass", a_DOM_element);
debería ser más rápido que
$(".myclass");
si ya tiene un elemento_DOM y es significativamente más pequeño que el documento completo.
He estado en algunas de las listas de correo jQuery y, por lo que he leído allí, lo más probable es que filtren por nombre de etiqueta y nombre de clase (o viceversa si fuera más rápido). Son obsesivos con la velocidad y usarían cualquier cosa para obtener una pizca de rendimiento.
Realmente no me preocuparía demasiado de todos modos a menos que esté ejecutando ese selector miles de veces / seg.
Si realmente está preocupado, intente hacer una evaluación comparativa y vea cuál es más rápido.
No hay duda de que filtrar por nombre de etiqueta primero es mucho más rápido que filtrar por nombre de clase.
Este será el caso hasta que todos los navegadores implementen getElementsByClassName de forma nativa, como es el caso de getElementsByTagName.
Otro lugar para buscar información sobre el rendimiento es la página Análisis de Desempeño de los selectores de Hugo Vidal Teixeira.
Esto proporciona una buena disminución de las velocidades para el selector por id, selector por clase y nombre de etiqueta de prefijación del selector.
Los selectores más rápidos por id fue: $ ("# id")
El selector más rápido por clase fue: $ (''tag.class'')
¡Así que prefijar por etiqueta solo ayudó cuando se seleccionó por clase!
Para comprender completamente qué es más rápido, debes entender cómo funciona el analizador de CSS.
El selector que pasa se divide en partes reconocibles usando RegExp y luego se procesa pieza por pieza.
Algunos selectores, como ID y TagName, usan la implementación nativa del navegador, que es más rápida. Mientras que otros, como la clase y los atributos, se programan por separado y, por lo tanto, son mucho más lentos, lo que requiere pasar por los elementos seleccionados y verificar todos y cada uno de los nombres de las clases.
Entonces sí para responder su pregunta:
$ (''tag.class'') es más rápido que solo $ (''. clase''). ¿Por qué? Con el primer caso, jQuery usa la implementación del navegador nativo para filtrar la selección a solo los elementos que necesita. Solo entonces lanza la implementación de clase más lenta filtrándose a lo que usted solicitó.
En el segundo caso, jQuery usa su método para filtrar cada elemento al tomar la clase.
Esto se extiende más allá de jQuery ya que todas las bibliotecas de JavaScript se basan en esto. La única otra opción es usar xPath pero actualmente no es muy compatible con todos los navegadores.
Si no me equivoco, jQuery también es un motor de abajo hacia arriba. Eso significa que $(''#foo bar div'')
es mucho más lento que $(''bar div #foo'')
. Por ejemplo, $(''#foo a'')
revisará todos los elementos a en la página y verá si tienen un antecesor de #foo
, lo que hace que este selector sea inmensamente ineficiente.
Resig ya puede haber optimizado para este escenario (no me sorprendería si lo hiciera, creo que lo hizo en su motor Sizzle, pero no estoy 100% seguro).
Un gran consejo de una pregunta que hice: use selectores de CSS estándar siempre que sea posible. Esto permite a jQuery usar la API de Selectores . Según las pruebas realizadas por John Resig , esto resulta en un rendimiento casi nativo para los selectores. Se deben evitar funciones como :has()
y :contains()
.
Desde mi investigación, el soporte para la API Selectors se introdujo con jQuery 1.2.7, Firefox 3.1, IE 8, Opera 10, Safari 3.1.