¿Qué es niños más rápidos () o find () en jQuery?

320

Para seleccionar un nodo hijo en jQuery, se puede usar children () pero también find ().

Por ejemplo:

$(this).children('.foo');

da el mismo resultado que:

$(this).find('.foo');

Ahora, ¿qué opción es la más rápida o preferida y por qué?

bart
fuente
27
.find()y .children()no son lo mismo Este último solo viaja un solo nivel hacia abajo en el árbol DOM, como un selector secundario.
Timothy003
1
@ Timothy003 Lo has descrito mal, el primero viaja solo un nivel hacia abajo, no el segundo
Dipesh Rana
55
@DipeshRana el 'último' aplicado a la propia oración de Timothy003, no a la pregunta
Jayesh Bhoot
1
Gracias por mencionar este problema. En muchos casos, la diferencia de rendimiento es trivial, ¡pero los documentos en realidad no mencionan que estos dos métodos se implementan de manera diferente! En aras de las mejores prácticas, es bueno saber que find()casi siempre es más rápido.
Steve Benner,
Es por eso que nunca me gustó la construcción "la primera" o "la última" en inglés. Solo di a cuál te refieres. Sheesh
Chris Walker

Respuestas:

415

children()solo mira a los hijos inmediatos del nodo, mientras find()atraviesa todo el DOM debajo del nodo, por lo que children() debería ser más rápido con implementaciones equivalentes. Sin embargo, find()usa métodos de navegador nativos , mientras que children()usa JavaScript interpretado en el navegador. En mis experimentos no hay mucha diferencia de rendimiento en casos típicos.

El uso depende de si solo desea considerar los descendientes inmediatos o todos los nodos debajo de este en el DOM, es decir, elegir el método apropiado en función de los resultados que desee, no la velocidad del método. Si el rendimiento es realmente un problema, entonces experimente para encontrar la mejor solución y úsela (o vea algunos de los puntos de referencia en las otras respuestas aquí).

tvanfosson
fuente
99
Claro, pero ¿qué sucede si el elemento padre solo tiene nodos hijos? Voy a hacer algunos perfiles sobre esto.
jason
11
El rendimiento de children vs find depende del navegador y de cuán complejo es el subárbol DOM que está buscando. En los navegadores modernos, find () usa internamente querySelectorAll, que puede superar fácilmente a los hijos () en un selector complejo y en un subárbol DOM pequeño a moderado.
LeJared
Ayudaría a proporcionar algunos resultados cuantitativos de sus experimentos.
Lucas
Para mí, en todas las pruebas con jerarquizaciones entre 5 y 20, find () siempre superó a los hijos (). (probado en Google Chrome 54) Esperaba lo contrario. Entonces, de ahora en adelante, tomaré el camino fácil y encontraré (...) mis elementos en lugar de atravesarlos a través de children (). Children (). Children () ...
Ruwen
179

Esta prueba jsPerf sugiere que find () es más rápido. Creé una prueba más exhaustiva , y todavía parece que find () supera a los niños ().

Actualización: según el comentario de tvanfosson, creé otro caso de prueba con 16 niveles de anidamiento. find () solo es más lento cuando se encuentran todos los divs posibles, pero find () aún supera a los hijos () al seleccionar el primer nivel de divs.

children () comienza a superar a find () cuando hay más de 100 niveles de anidamiento y alrededor de 4000+ divs para find () para atravesar. Es un caso de prueba rudimentario, pero sigo pensando que find () es más rápido que los niños () en la mayoría de los casos.

Pasé por el código jQuery en Chrome Developer Tools y noté que children () internamente hace llamadas a sibling (), filter (), y pasa por algunas expresiones regulares más que find ().

find () y children () satisfacen diferentes necesidades, pero en los casos en que find () y children () generarían el mismo resultado, recomendaría usar find ().

JR
fuente
44
Parece que los niños usan métodos transversales de dom y find usa el api selector, que es más rápido.
topek
44
Caso de prueba bastante degenerado ya que solo tiene un nivel de anidamiento. Si desea el caso general, tendrá que configurar algunas profundidades de anidación arbitrarias y verificar el rendimiento ya que find () atraviesa árboles más profundos que los hijos ().
tvanfosson
Si está comprobando si un elemento secundario singular específico (por ejemplo, event.target) está en un elemento dom específico (por ejemplo, $ ('. Navbar')), entonces $ .contains (esto, event.target) es, con mucho, el más rápido (8.433.609 / segundo frente a 140k para la búsqueda de jquery más rápida). jsperf.com/child-is-in-parent
Chris Sattinger
92

Aquí hay un enlace que tiene una prueba de rendimiento que puede ejecutar. find()en realidad es aproximadamente 2 veces más rápido que children().

Chrome en OSX10.7.6

mactive
fuente
$ .contains (document.getElementById ('list'), $ ('. test') [0]) es 8.433.609 / segundo. Si tiene elementos específicos y solo quiere saber si B está en A, entonces este es el mejor. jsperf.com/child-is-in-parent
Chris Sattinger
Buena prueba Tenga en cuenta que puede ser aún más rápido si hace algo como var $test = $list.find('.test');donde $ list es un objeto jQuery. jsperf.com/jquery-selectors-context/101
Maciej Krawczyk
24

Esos no necesariamente darán el mismo resultado: find()obtendrán cualquier nodo descendiente , mientras children()que solo obtendrán hijos inmediatos que coincidan.

En un momento, find()fue mucho más lento ya que tenía que buscar todos los nodos descendientes que pudieran coincidir, y no solo los hijos inmediatos. Sin embargo, esto ya no es cierto; find()es mucho más rápido debido al uso de métodos de navegador nativos.

John Feminella
fuente
1
No según las otras respuestas jaja: p. Solo cuando tienes un árbol DOM muy, muy grande ...
pgarciacamou
1
@Camou Esta respuesta tiene cuatro años. find()fue mucho más lento en ese momento!
John Feminella
@camou dice que la parte de rendimiento fue "No según las otras respuestas". El primer párrafo de esta respuesta es exacto.
Don Cheadle
14

Ninguna de las otras respuestas se refirió al caso de usar .children()o .find(">")que solamente buscar hijos inmediatos de un elemento padre. Entonces, creé una prueba jsPerf para averiguarlo , usando tres formas diferentes para distinguir a los niños.

De hecho, incluso cuando se usa el selector ">" adicional, .find()sigue siendo mucho más rápido que .children(); en mi sistema, 10 veces más.

Entonces, desde mi punto de vista, no parece haber muchas razones para usar el mecanismo de filtrado .children().

Craig Walker
fuente
3
¡Gracias por este comentario! Me pregunto si jQuery debería cambiar a hacer que .children (x) sea un alias para .find (">" + x), aunque probablemente haya otras complicaciones en las que no estoy pensando.
Michael Scott Cuthbert
1
Esta parece ser la comparación más apropiada. ¡Gracias!
GollyJer
3

Ambos find()y los children()métodos se utilizan para filtrar el elemento secundario de los elementos coincidentes, excepto que el primero se desplaza cualquier nivel hacia abajo, el último se desplaza un solo nivel hacia abajo.

Simplificar:

  1. find() - busca a través de elementos coincidentes hijo, nieto, bisnieto ... todos los niveles hacia abajo.
  2. children() - buscar solo en el elemento secundario de los elementos coincidentes (nivel inferior).
Naresh Kumar
fuente