Pergunta

Estou procurando uma maneira de melhorar o desempenho do seletor de uma chamada jQuery.Especificamente coisas como esta:

É $("div.myclass") mais rápido que $(".myclass")

Eu acho que pode ser, mas não sei se o jQuery é inteligente o suficiente para limitar a pesquisa primeiro pelo nome da tag, etc.Alguém tem alguma idéia de como formular uma string seletora jQuery para melhor desempenho?

Foi útil?

Solução

Não existe dúvida que filtrar primeiro pelo nome da tag é muito mais rápido do que filtrar por nome de classe.

Este será o caso até que todos os navegadores implementem getElementsByClassName nativamente, como é o caso de getElementsByTagName.

Outras dicas

Em alguns casos, você pode acelerar uma consulta limitando seu contexto.Se você tiver uma referência de elemento, poderá passá-la como segundo argumento para limitar o escopo da consulta:

$(".myclass", a_DOM_element);

deveria ser mais rápido que

$(".myclass");

se você já possui um_DOM_element e ele é significativamente menor que o documento inteiro.

Como Reid afirmou acima, o jQuery está funcionando de baixo para cima.Embora

que significa $('#foo bar div') é muito mais lento do que $('bar div #foo')

Essa não é a questão.Se você tinha #foo você não colocaria nada antes no seletor, pois os IDs precisam ser exclusivos.

A questão é:

  • se você estiver subselecionando qualquer coisa de um elemento com um ID, selecione o último primeiro e depois use .find, .children etc.: $('#foo').find('div')
  • sua parte mais à esquerda (primeira) do seletor pode ser menos eficiente escalar para a parte mais à direita (última) que deve seja o mais eficiente - ou seja, se você não tiver uma identificação, certifique-se de estar procurando $('div.common[slow*=Search] input.rare') em vez de $('div.rare input.common[name*=slowSearch]') - como isso nem sempre é aplicável, certifique-se de forçar a ordem do seletor dividindo de acordo.

Para compreender totalmente o que é mais rápido, você precisa entender como funciona o analisador CSS.

O seletor que você passa é dividido em partes reconhecíveis usando RegExp e depois processado peça por peça.

Alguns seletores como ID e TagName usam a implementação nativa do navegador, que é mais rápida.Enquanto outros, como classes e atributos, são programados separadamente e, portanto, são muito mais lentos, exigindo um loop pelos elementos selecionados e a verificação de cada nome de classe.

Então, sim, para responder à sua pergunta:

$('tag.class') é mais rápido que apenas $('.class').Por que?No primeiro caso, o jQuery usa a implementação nativa do navegador para filtrar a seleção apenas para os elementos necessários.Só então ele inicia a implementação .class mais lenta, filtrando o que você solicitou.

No segundo caso, o jQuery usa seu método para filtrar cada elemento, capturando a classe.

Isso vai além do jQuery, pois todas as bibliotecas javascript são baseadas nele.A única outra opção é usar o xPath, mas atualmente não é muito bem suportado por todos os navegadores.

Veja como aumentar o desempenho dos seus seletores jQuery:

Acrescentarei uma observação de que em 99% dos aplicativos da web, mesmo os aplicativos pesados ​​em ajax, a velocidade de conexão e a resposta do servidor da web irão impulsionar o desempenho do seu aplicativo, em vez do javascript.Não estou dizendo que você deve escrever código intencionalmente lento ou que geralmente estar ciente de que coisas provavelmente serão mais rápidas que outras não é bom.

Mas estou me perguntando se você está tentando resolver um problema que ainda não existe, ou mesmo se está otimizando para algo que pode mudar num futuro próximo (digamos, se mais pessoas começarem a usar um navegador que suporte getElementsByClassName() função mencionada anteriormente), fazendo com que seu código otimizado seja executado mais lentamente.

Outro local para procurar informações de desempenho é a página Análise de desempenho de seletores de Hugo Vidal Teixeira.

http://www.componenthouse.com/article-19

Isso fornece uma boa estimativa das velocidades do seletor por id, do seletor por classe e do nome da tag de prefixo do seletor.

Os seletores mais rápidos por id foram:$("#id")

O seletor mais rápido por classe foi:$('tag.class')

Portanto, prefixar por tag só ajudou na seleção por classe!

Estive em algumas listas de discussão do jQuery e, pelo que li lá, elas provavelmente filtram por nome de tag e depois por nome de classe (ou vice-versa, se for mais rápido).Eles são obsessivos por velocidade e usariam qualquer coisa para obter um pouquinho de desempenho.

Eu realmente não me preocuparia muito com isso, a menos que você esteja executando esse seletor milhares de vezes/seg.

Se você estiver realmente preocupado, tente fazer alguns benchmarking e veja qual é mais rápido.

Considere usar a biblioteca Sequentially de Oliver Steele para chamar métodos ao longo do tempo, em vez de todos de uma vez.

http://osteele.com/sources/javascript/sequentially/

O método "eventualmente" ajuda a chamar um método após um determinado período de tempo desde sua chamada inicial.O método "sequencialmente" permite enfileirar várias tarefas durante um período de tempo.

Muito útil!

A ótima dica de uma pergunta que fiz:Usar seletores CSS padrão qualquer lugar possível.Isso permite que o jQuery use o API de seletores.De acordo com testes realizados por John Resig, isso resulta em desempenho quase nativo para seletores.Funções como :has() e :contains() Deveria ser evitado.

Da minha pesquisa, o suporte para a API Selectors foi introduzido com jQuery 1.2.7, Firefox 3.1, IE 8, Opera 10, Safari 3.1.

Se não me engano, o jQuery também é um mecanismo bottom-up.Que significa $('#foo bar div') é muito mais lento do que $('bar div #foo').Por exemplo, $('#foo a') passará por todos os a elementos na página e ver se eles têm um ancestral de #foo, o que torna esse seletor imensamente ineficiente.

Resig pode já ter otimizado para este cenário (não me surpreenderia se o fizesse - acredito que o fez em seu mecanismo Sizzle, mas não tenho 100% de certeza).

Acredito que selecionar primeiro por ID é sempre mais rápido:

$("#myform th").css("color","red");

deveria ser mais rápido que

$("th").css("color","red");

Porém, me pergunto o quanto o encadeamento ajuda quando se inicia com o ID?É isto

$("#myform").find("th").css("color","red")
.end().find("td").css("color","blue");

mais rápido que isso?

$("#myform th").css("color","red");
$("#myform td").css("color","blue");
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top