javascript page Buoni modi per migliorare le prestazioni del selettore jQuery?




jquery modify title page (10)

Sto cercando un modo per migliorare le prestazioni del selettore di una chiamata jQuery. Specificamente cose come questa:

$("div.myclass") più veloce di $(".myclass")

Penso che potrebbe essere, ma non so se jQuery sia abbastanza intelligente da limitare la ricerca per nome del tag prima, ecc. Qualcuno ha qualche idea su come formulare una stringa di selettore jQuery per le migliori prestazioni?


Se non sbaglio, jQuery è anche un motore bottom-up. Ciò significa che $('#foo bar div') è molto più lento di $('bar div #foo') . Ad esempio, $('#foo a') passerà attraverso tutti gli elementi sulla pagina e vedrà se hanno un antenato di #foo , il che rende immensamente inefficiente questo selettore.

Resig potrebbe aver già ottimizzato questo scenario (non mi sorprenderebbe se lo avesse fatto - credo che l'abbia fatto nel suo motore Sizzle, ma non ne sono sicuro al 100%.)


Aggiungerò una nota che nel 99% delle app Web, anche delle app ajax pesanti, la velocità di connessione e la risposta del server Web determineranno le prestazioni della tua app piuttosto che il javascript. Non sto dicendo che dovresti scrivere codice intenzionalmente lento o che generalmente ti accorgi delle cose che sono probabilmente più veloci di altre.

Ma mi chiedo se stai cercando di risolvere un problema che ancora non esiste, o anche se stai ottimizzando qualcosa che potrebbe cambiare nel prossimo futuro (diciamo, se più persone iniziano a utilizzare un browser che supporta getElementsByClassName() funzione di cui sopra), rendendo il vostro codice ottimizzato effettivamente eseguito più lentamente.


Prendi in considerazione l'utilizzo della libreria Sequentially di Oliver Steele per chiamare i metodi nel tempo anziché tutti contemporaneamente.

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

Il metodo "alla fine" ti aiuta a chiamare un metodo dopo un certo periodo di tempo dalla sua chiamata iniziale. Il metodo "sequenzialmente" consente di mettere in coda diverse attività per un periodo di tempo.

Molto utile!


Sono stato in alcune delle mailing list di jQuery e da quello che ho letto lì, probabilmente filtrano per nome del tag e nome della classe (o viceversa se fosse più veloce). Sono ossessionati dalla velocità e userebbero qualsiasi cosa per ottenere un pizzico di prestazioni.

Non me ne preoccuperei molto comunque, a meno che tu non stia eseguendo quel selettore migliaia di volte / sec.

Se sei davvero preoccupato, prova a fare un benchmarking e vedi quale è più veloce.


Per comprendere appieno ciò che è più veloce, devi capire come funziona il parser CSS.

Il selettore che passi è diviso in parti riconoscibili usando RegExp e poi elaborato pezzo per pezzo.

Alcuni selettori come ID e TagName, utilizzano l'implementazione nativa del browser che è più veloce. Mentre altri come la classe e gli attributi sono programmati separatamente e quindi sono molto più lenti, richiedono il looping tra gli elementi selezionati e il controllo di ogni nome di classe.

Quindi sì per rispondere alla tua domanda:

$ ('tag.class') è più veloce di $ ('. classe'). Perché? Con il primo caso, jQuery utilizza l'implementazione nativa del browser per filtrare la selezione in basso solo per gli elementi necessari. Solo in seguito viene avviata l'implementazione di classe .class più lenta fino a quello che hai chiesto.

Nel secondo caso, jQuery usa il suo metodo per filtrare ogni elemento catturando la classe.

Questo si diffonde ulteriormente rispetto a jQuery poiché tutte le librerie javascript sono basate su questo. L'unica altra opzione è usare xPath ma al momento non è molto ben supportato da tutti i browser.


In alcuni casi, puoi velocizzare una query limitando il suo contesto. Se si dispone di un riferimento di elemento, è possibile passarlo come secondo argomento per limitare l'ambito della query:

$(".myclass", a_DOM_element);

dovrebbe essere più veloce di

$(".myclass");

se hai già a_DOM_element ed è significativamente più piccolo dell'intero documento.


Non c'è dubbio che il filtraggio per nome del tag prima sia molto più veloce del filtraggio in base al nome della classe.

Questo avverrà fino a quando tutti i browser implementeranno getElementsByClassName in modo nativo, come nel caso di getElementsByTagName.


Un altro posto dove cercare informazioni sulle prestazioni è la pagina Analisi dell'analisi dei selettori di Hugo Vidal Teixeira.

componenthouse.com/article-19

Ciò offre una buona riduzione delle velocità per il selettore per id, selettore per classe e nome del prefisso del selettore.

I selettori più veloci per id erano: $ ("# id")

Il selettore più veloce per classe era: $ ('tag.class')

Quindi il prefisso per tag ha aiutato solo quando si seleziona per classe!


Un ottimo consiglio da una domanda che ho posto: Usa i selettori CSS standard ovunque sia possibile. Ciò consente a jQuery di utilizzare l' API dei selettori . Secondo i test eseguiti da John Resig , ciò si traduce in prestazioni quasi native per i selettori. Funzioni come :has() e :contains() dovrebbero essere evitate.

Dal mio supporto di ricerca per l'API Selectors è stata introdotta con jQuery 1.2.7, Firefox 3.1, IE 8, Opera 10, Safari 3.1.


Come affermato da Reid sopra, jQuery funziona dal basso verso l'alto. Sebbene

ciò significa che $('#foo bar div') è molto più lento di $('bar div #foo')

Non è questo il punto. Se avessi #foo non avresti mai inserito nulla nel selettore, dal momento che gli ID devono essere unici.

Il punto è:

  • se stai sottolineando qualcosa da un elemento con un ID, seleziona prima quello successivo e poi usa .find , .children ecc .: $('#foo').find('div')
  • la parte più a sinistra (prima) del selettore può essere ridimensionata in modo meno efficace alla parte (ultima) più a destra che dovrebbe essere la più efficiente, ovvero se non si dispone di un ID, assicurarsi di cercare $('div.common[slow*=Search] input.rare') piuttosto che $('div.rare input.common[name*=slowSearch]') - poiché questo non è sempre applicabile assicurati di forzare l'ordine del selettore suddividendolo di conseguenza.




css-selectors