O que são filhos mais rápidos () ou find () no jQuery?

320

Para selecionar um nó filho no jQuery, pode-se usar children (), mas também find ().

Por exemplo:

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

dá o mesmo resultado que:

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

Agora, qual opção é mais rápida ou preferida e por quê?

bart
fonte
27
.find()e .children()não são os mesmos. O último viaja apenas um único nível na árvore do DOM, como um seletor filho.
Timothy003
1
@ Timothy003 Você descreveu-o errado, o anterior viaja único nível baixo não o último
Dipesh Rana
5
@DipeshRana, o 'último' aplicado à sentença de Timothy003, não à pergunta.
Jayesh Bhoot
1
Obrigado por abordar esta questão. Em muitos casos, a diferença de desempenho é trivial, mas os documentos não mencionam que esses dois métodos são implementados de maneira diferente! Em prol das melhores práticas, é bom saber que find()quase sempre é mais rápido.
Steve Benner
É por isso que nunca gostei da construção "o primeiro" ou "o último" em inglês. Apenas diga qual você quer dizer. Sheesh.
Chris Walker

Respostas:

415

children()apenas analisa os filhos imediatos do nó, enquanto find()percorre todo o DOM abaixo do nó, portanto, children() deve ser mais rápido com implementações equivalentes. No entanto, find()usa métodos nativos do navegador, enquanto children()usa JavaScript interpretado no navegador. Nas minhas experiências, não há muita diferença de desempenho em casos típicos.

O qual usar depende se você deseja considerar apenas os descendentes imediatos ou todos os nós abaixo deste no DOM, ou seja, escolha o método apropriado com base nos resultados desejados, não na velocidade do método. Se o desempenho for realmente um problema, experimente encontrar a melhor solução e use-a (ou veja alguns dos benchmarks nas outras respostas aqui).

tvanfosson
fonte
9
Claro, mas o que acontece se o elemento pai tiver apenas nós filhos? Eu vou fazer alguns perfis sobre isso.
jason
11
O desempenho de children vs find depende do navegador e de quão complexa a subárvore DOM é sua pesquisa. Nos navegadores modernos, o find () usa internamente o querySelectorAll, que pode facilmente superar o children () no seletor complexo e na subárvore DOM pequena a moderada.
LeJared
Ajudaria a fornecer alguns resultados quantitativos de suas experiências.
Luke
Para mim, em todos os testes com aninhamentos de hierarquia entre 5 e 20, find () sempre superou crianças (). (testado no Google Chrome 54) Eu esperava o contrário. Então, de agora em diante, eu vou tomar o caminho mais fácil e encontrar (...) meus elementos em vez de percorrer-los via crianças () crianças () children () .....
Ruwen
179

Esse teste jsPerf sugere que find () é mais rápido. Eu criei um teste mais completo e ainda parece que find () supera children ().

Atualização: conforme o comentário do tvanfosson, criei outro caso de teste com 16 níveis de aninhamento. find () é apenas mais lento ao encontrar todos os divs possíveis, mas find () ainda supera child () ao selecionar o primeiro nível de divs.

children () começa a superar find () quando há mais de 100 níveis de aninhamento e cerca de 4000 divs para find () a percorrer. É um caso de teste rudimentar, mas ainda acho que find () é mais rápido que crianças () na maioria dos casos.

Consultei o código jQuery nas Ferramentas para desenvolvedores do Chrome e notei que children () faz chamadas internamente para sibling (), filter () e passa por mais algumas regexes do que find ().

find () e children () atendem a necessidades diferentes, mas nos casos em que find () e children () produziriam o mesmo resultado, eu recomendaria o uso de find ().

JR.
fonte
4
Parece que children usa métodos de passagem dom e find usa o seletor api, que é mais rápido.
Top11
4
Caso de teste bastante degenerado, pois você só tem um nível de aninhamento. Se você quiser o caso geral, precisará configurar algumas profundidades de aninhamento arbitrárias e verificar o desempenho, pois find () atravessa árvores mais profundas do que as crianças ().
315:
Se você está verificando se um elemento filho singular específico (por exemplo, event.target) está em um elemento dom específico (por exemplo, $ ('. Navbar')), então $ .contains (this, event.target) é de longe o mais rápido (8.433.609 / segundo vs 140k para a pesquisa jquery mais rápida). jsperf.com/child-is-in-parent
Chris Sattinger
92

Aqui está um link que possui um teste de desempenho que você pode executar. find()é na verdade cerca de 2 vezes mais rápido que children().

Chrome no OSX10.7.6

mactive
fonte
$ .contains (document.getElementById ('list'), $ ('. test') [0]) é 8.433.609 / segundo. Se você possui elementos específicos e deseja apenas saber se B está em A, então é melhor. jsperf.com/child-is-in-parent
Chris Sattinger
Bom teste. Observe que pode ser ainda mais rápido se você fizer algo como var $test = $list.find('.test');onde $ list é o objeto jQuery. jsperf.com/jquery-selectors-context/101
Maciej Krawczyk
24

Isso não necessariamente dará o mesmo resultado: find()você obterá qualquer nó descendente , enquanto children()apenas os filhos imediatos correspondentes.

A certa altura, find()era muito mais lento, pois era necessário procurar todos os nós descendentes que pudessem corresponder, e não apenas filhos imediatos. No entanto, isso não é mais verdade; find()é muito mais rápido devido ao uso de métodos nativos do navegador.

John Feminella
fonte
1
Não de acordo com as outras respostas haha: p. Somente quando você tem uma árvore DOM muito, muito, muito grande ..
pgarciacamou
1
@ Camou Esta resposta tem quatro anos. find()era muito mais lento na época!
John Feminella
@camou está dizendo que a parte do desempenho foi "Não de acordo com as outras respostas". O primeiro parágrafo desta resposta é preciso.
Don Cheadle
14

Nenhuma das outras respostas lidou com o caso de utilização .children()ou .find(">")a única procurar filhos imediatos de um elemento pai. Então, criei um teste jsPerf para descobrir , usando três maneiras diferentes de distinguir filhos.

Por acaso, mesmo ao usar o seletor ">" extra, .find()ainda é muito mais rápido que .children(); no meu sistema, 10x isso.

Portanto, da minha perspectiva, não parece haver muitos motivos para usar o mecanismo de filtragem .children().

Craig Walker
fonte
3
Obrigado por este comentário! Gostaria de saber se o jQuery deveria apenas mudar para tornar .children (x) um alias para .find (">" + x), embora provavelmente haja outras complicações nas quais não estou pensando.
Michael Scott Cuthbert
1
Essa parece ser a comparação mais apropriada. Obrigado!
GollyJer
3

Ambos find()e children()métodos são usados para filtrar a criança dos elementos emparelhados, excepto o primeiro é qualquer viaja para baixo nível, o último é viaja para baixo um único nível.

Para simplificar:

  1. find() - pesquise o filho, neto, bisneto dos elementos correspondentes ... todos os níveis.
  2. children() - pesquise somente o filho dos elementos correspondentes (nível único abaixo).
Naresh Kumar
fonte