Domanda

Sto riscontrando enormi variazioni nelle prestazioni a seconda di come esprimo i miei selettori. Ad esempio, guarda questi 2 selettori, che selezionano esattamente gli stessi elementi:

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

Mi aspetto che B) sia più veloce poiché c'è solo 1 chiamata, ma in realtà sto trovando A) viene eseguito circa 8 volte più veloce. Non ho idea del perché, qualcuno ha qualche intuizione? Grazie

È stato utile?

Soluzione

Supponendo che tu stia utilizzando almeno jQuery 1.3 (ovvero con l'aggiunta di Sizzle), le prestazioni che stai vedendo sono dovute al cambiamento in cui viene attraversato il DOM. Da qui :

  

Fino a jQuery 1.2.6 incluso il   il motore del selettore funzionava in modo "top down"   (o "da sinistra a destra"). jQuery   1.3.x (ovvero Sizzle , che jQuery incorpora) ha introdotto un " bottom up " ; (o   Approccio alla query "da destra a sinistra"   il DOM.

Nel tuo secondo esempio ( " td.someColumnClass span.editMode input " ), Sizzle lo fa efficacemente:

  1. ottieni tutti gli elementi input all'interno di someTableRow
  2. per ogni elemento input trovato, attraversa il suo albero degli antenati per gli elementi span con class = " editMode " . Rimuovi gli elementi input che non hanno questi antenati
  3. per ogni elemento span.editMode trovato, attraversa l'albero dei suoi antenati per gli elementi td con class = " someColumnClass " . Rimuovi gli elementi input che non hanno questi antenati

Nel tuo primo esempio, tuttavia, stai qualificando esplicitamente ogni passaggio con ogni chiamata a find () , definendo un contesto e attraversando giù da lì. Stai imponendo il "top-down" approccio. È equivalente a passare in un contesto ad ogni passaggio, che è generalmente considerato un booster di prestazioni :

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

Altri suggerimenti

Perché stai riducendo il contesto per la ricerca.

Nel caso B, deve cercare in ogni elemento DOM per vedere se soddisfa i criteri.

Nel caso A, è possibile decidere rapidamente di ignorare tutto ciò che non è " td.someColumnClass " ;, quindi può prendere quel sottoinsieme del DOM e ignorare tutto ciò che non è in " span.editMode " ;. Quindi ha una serie molto più piccola di elementi da cercare per trovare "input" adesso.

A sono più chiamate, ma più semplici. B è una chiamata, ma più complessa. In questo caso, la complessità della chiamata supera di gran lunga la quantità di chiamate.

Il modo in cui JQuery gestisce i selettori è un po 'diverso dal CSS nella mia esperienza.

Ridurre il contesto alla ricerca è la chiave come ha sottolineato Josh.

Trovo che usare i due selettori di parametri sia molto veloce

Come si confronta la velocità saggia?

Non hai bisogno di tutti i parametri qui è solo per chiarire quello che sto facendo.

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

La gentilezza,

Dan

Ho fatto alcune ricerche su jQuery Selector Performance da solo. Un grosso problema sono le ricerche per nome classe su Internet Explorer. IE non supporta getElementsByClassName - pertanto jQuery e altri framework "reimplement" in JavaScript ripetendo tutti gli elementi DOM. Consulta il seguente blog di analisi su jQuery Selector Performance

C'è un articolo davvero interessante sulle prestazioni dei selettori qui: http: // blogs .atlassian.com / developer / 2009/08 / jquery_bondage.html

In esso, l'autore mostra un "quot" bind " Estensione jQuery che mostra quante volte viene valutata la funzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top