Pergunta

Eu estou tendo grandes variações de desempenho, dependendo de como eu expressar meus seletores. Por exemplo, olhar para estes 2 seletores, que selecionar exatamente os mesmos elementos:

A) someTableRow.find("td.someColumnClass").find("span.editMode").find("input")
B) someTableRow.find("td.someColumnClass span.editMode input")

Eu esperaria B) para ser mais rápido, há apenas 1 chamada, mas na verdade eu estou achando A) executa cerca de 8 vezes mais rápido. Eu não tenho idéia por que, alguém tem alguma idéia? Graças

Foi útil?

Solução

Supondo que você está usando pelo menos jQuery 1.3 (ou seja, com a adição de Sizzle), o desempenho que você está vendo é devido à mudança em que o DOM é atravessado. De aqui :

Até e incluindo jQuery 1.2.6 do motor selector trabalhou em um "down top" (Ou "esquerda para a direita") forma. jQuery 1.3.x (ou seja, chiar , que incorpora jQuery) introduziu um "-se inferior" (ou "Direita para a esquerda") abordagem para consulta DOM.

Em seu segundo exemplo ("td.someColumnClass span.editMode input"), Sizzle efetivamente faz isso:

  1. obter todos os elementos input dentro someTableRow
  2. para cada elemento input encontrado, atravessar a sua árvore ancestral para elementos span com class="editMode". Remover elementos input que não têm esses ancestrais
  3. para cada elemento span.editMode encontrado, atravessar a sua árvore ancestral para elementos td com class="someColumnClass". Remover elementos input que não têm esses ancestrais

Em seu primeiro exemplo no entanto, você está qualificando cada etapa explicitamente com cada chamada para find(), definindo um contexto e atravessando abaixo de lá. Você está aplicando a abordagem "top-down". É equivalente ao passar num contexto em cada etapa, o que é geralmente considerado um desempenho reforço:

$('input', $('span.editMode', $('td.someColumnClass', someTableRow)))

Outras dicas

Porque você está reduzindo o contexto para a pesquisa.

No caso B, tem que pesquisar através de cada elemento DOM para ver se ele atende aos critérios.

No caso de A, é rapidamente pode decidir ignorar qualquer coisa que não é "td.someColumnClass", então ele pode tomar esse subconjunto do DOM e ignorar qualquer coisa que não está em "span.editMode". Por isso, tem um conjunto muito menor de elementos a pesquisar para encontrar "input" é agora.

A é mais chamadas, mas mais simples. B é uma chamada, mas mais complexa. Neste caso, a complexidade da chamada muito out-pesa a quantidade de chamadas.

A forma como as alças JQuery selctors é um pouco diferente para CSS na minha experiência.

Reduzir o contexto para a pesquisa é a chave como Josh apontou.

I encontrar usando os dois seletores de parâmetros muito rápido

Como é que esta velocidade comparar sábio?

Você não precisa de todos os vars aqui é apenas para deixar claro o que estou fazendo.

var columnClasses = $('.someColumnClass');
var tableCell = $('td', columnclasses);
var editMode = $('.editmode', tableCell);
var spanInside = $('span', editMode);
var inputFinally = $('input', spanInside);

Bondade,

Dan

Eu fiz alguma pesquisa sobre jQuery Selector Desempenho mim. Um grande problema são as pesquisas por nome de classe no Internet Explorer. IE suporte does not getElementsByClassName - portanto, jQuery e outras estruturas "Reimplementar"-lo em JavaScript por iteração através de todos os elementos DOM. Confira a seguir blogue análise sobre jQuery Selector Desempenho

Há um artigo muito interessante sobre o desempenho selector aqui: http: // blogs .atlassian.com / desenvolvedor / 2009/08 / jquery_bondage.html

Nele, o autor mostra um "bind" extensão jQuery que mostra quantas vezes a função é avaliada.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top