2009-03-15 32 views
279

Para seleccionar un nodo secundario en jQuery uno puede usar children() pero también find().¿Qué es children() o find() más rápido en jQuery?

Por ejemplo:

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

da el mismo resultado que:

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

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

+21

'.find()' y '.children()' no son lo mismo. Este último solo recorre un único nivel en el árbol DOM, como un selector de niños. – Timothy003

+1

@ Timothy003 Usted lo ha descrito mal, el anterior viaja solo nivel abajo no el último –

+2

@DipeshRana el 'último' se aplicó a la propia oración de Timothy003, no la pregunta. –

Respuesta

369

children() sólo se ve en los hijos inmediatos del nodo, mientras que find() atraviesa todo el DOM por debajo del nodo, por lo children() debería ser más rápido dado 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.

Qué usar depende de si solo desea considerar los descendientes inmediatos o todos los nodos debajo de este en el DOM, es decir, elija el método apropiado según 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 use eso (o vea algunos de los puntos de referencia en las otras respuestas aquí).

+8

Claro, pero ¿qué ocurre si el elemento padre solo tiene nodos secundarios? Voy a hacer un poco de perfil sobre esto. – jason

+3

@jason: ¿ha surgido algo de su perfil? –

+10

El rendimiento de los niños frente al hallazgo depende del navegador y de la complejidad de su búsqueda en el subárbol DOM. En los navegadores modernos, find() utiliza internamente querySelectorAll, que puede superar fácilmente a los elementos secundarios() en el selector complejo y en el subárbol DOM de pequeño a moderado. – LeJared

23

Aquellos no necesariamente dará el mismo resultado: find() le conseguirá cualquier nododescendiente, mientras que children() sólo va a llegar hijos inmediatos que coincidan.

En un punto, find() fue mucho más lento ya que tuvo que buscar cada nodo descendiente que pudiera coincidir, y no solo los secundarios. Sin embargo, esto ya no es verdad; find() es mucho más rápido debido al uso de métodos de navegador nativos.

+1

No según las otras respuestas jaja :pag . Solo cuando tienes un árbol DOM muy, muy, muy grande. – camou

+1

@Camou Esta respuesta tiene cuatro años. 'find()' ¡era mucho más lento en ese momento! –

+0

@camou dice que la parte de rendimiento fue "No según las otras respuestas". El primer párrafo de esta respuesta es exacto. – mmcrae

164

Este jsPerf test sugiere que find() es más rápido. Creé un more thorough test, y todavía parece que find() supera a los niños().

Actualización: Según el comentario de tvanfosson, creé another test case con 16 niveles de anidación. find() solo es más lento cuando se encuentran todos los div posibles, pero find() aún supera a children() cuando se selecciona el primer nivel de divs.

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

Pasé por el código de jQuery en Herramientas de desarrollo de Chrome y noté que children() internamente realiza llamadas a sibling(), filter() y realiza algunas expresiones más que find().

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

+4

Parece que los niños usan métodos de cruce dom y encuentran que usa la API de selector, que es más rápida. – topek

+4

Caso de prueba bastante degenerado ya que solo tiene un nivel de anidación. Si desea el caso general, deberá configurar algunas profundidades de anidamiento arbitrarias y comprobar el rendimiento, ya que find() atraviesa árboles más profundos que children(). – tvanfosson

+0

Si está comprobando si un elemento hijo singular específico (por ejemplo, evento.target) está en un elemento dom específico (por ejemplo, $ ('. Navbar')) entonces $ .contains (this, event.target) es de lejos el el más rápido (8,433,609/segundo frente a 140k para la búsqueda más rápida de jquery). http://jsperf.com/child-is-in-parent – felix

83

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

Chrome on OSX10.7.6

+0

$ .contains (document.getElementById ('list'), $ ('.prueba ') [0]) es 8.433.609/segundo. Si tiene elementos específicos y solo quiere saber si B está en A, entonces esto es lo mejor. http://jsperf.com/child-is-in-parent – felix

+0

Buena prueba. Tenga en cuenta que puede ser incluso más rápido si hace algo como 'var $ test = $ list.find ('. Test');' donde $ list es el objeto jQuery. http://jsperf.com/jquery-selectors-context/101 –

12

Ninguna de las otras respuestas que trata el caso de utilizar .children() o .find(">") a única búsqueda de niños inmediatos de un elemento padre. Entonces, creé un jsPerf test to find out, usando tres formas diferentes de distinguir niños.

Si llega el caso, incluso cuando se utiliza el ">" selector adicional, .find() es todavía mucho más rápido que .children(); en mi sistema, 10x entonces.

Por lo tanto, desde mi punto de vista, no parece haber muchas razones para utilizar el mecanismo de filtrado .children() en absoluto.

+2

¡Gracias por este comentario! Me pregunto si jQuery debería simplemente cambiar a hacer que .children (x) sea un alias para .find (">" + x), aunque probablemente haya otras complicaciones en las que no estoy pensando. –

+1

Esta parece ser la comparación más adecuada. ¡Gracias! – GollyJer

2

Tanto find() y children() métodos se utilizan para filtrar el niño de los elementos emparejados, excepto el primero es viaja cualquier nivel inferior, este último es viaja un solo nivel hacia abajo.

Para simplificar:

  1. find() - una búsqueda entre los elementos coincidentes niño, nieto, bisnieto ... todos los niveles hacia abajo.
  2. children() - busca a través del elemento emparejado 'hijo solamente (nivel único abajo).
Cuestiones relacionadas