Domanda

Sto cercando un modo per migliorare le prestazioni del selettore di una chiamata jQuery.Nello specifico cose del genere:

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

Penserei che potrebbe esserlo, ma non so se jQuery è abbastanza intelligente da limitare prima la ricerca in base al nome del tag, ecc.Qualcuno ha qualche idea su come formulare una stringa di selezione jQuery per ottenere le migliori prestazioni?

È stato utile?

Soluzione

Non c'è dubbio che filtrare prima in base al nome del tag è molto più veloce piuttosto che filtrare per nome classe.

Questo sarà il caso finché tutti i browser non implementeranno getElementsByClassName in modo nativo, come nel caso di getElementsByTagName.

Altri suggerimenti

In alcuni casi, puoi velocizzare una query limitandone il contesto.Se hai un riferimento a un elemento, puoi passarlo come secondo argomento per limitare l'ambito della query:

$(".myclass", a_DOM_element);

dovrebbe essere più veloce di

$(".myclass");

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

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

questo significa $('#foo bar div') è molto più lento di $('bar div #foo')

Non è questo il punto.Se tu avessi #foo non metteresti comunque nulla prima nel selettore poiché gli ID devono essere univoci.

Il punto è:

  • se stai sottoselezionando qualcosa da un elemento con un ID, seleziona prima il successivo e poi usa .find, .children eccetera.: $('#foo').find('div')
  • la parte più a sinistra (la prima) del selettore Potere essere meno efficiente ridimensionando la parte più a destra (ultima) che Dovrebbe sii il più efficiente, il che significa che se non hai un documento d'identità assicurati 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 di selezione suddividendolo di conseguenza.

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

Il selettore che passi viene suddiviso in parti riconoscibili utilizzando RegExp e quindi 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, richiedendo il ciclo degli elementi selezionati e il controllo del nome di ogni singola classe.

Quindi sì, per rispondere alla tua domanda:

$('tag.class') è più veloce di solo $('.class').Perché?Nel primo caso, jQuery utilizza l'implementazione nativa del browser per filtrare la selezione solo fino agli elementi necessari.Solo allora avvia l'implementazione .class più lenta filtrando fino a ciò che hai richiesto.

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

Questo si diffonde oltre jQuery poiché tutte le librerie JavaScript sono basate su questo.L'unica altra opzione è utilizzare xPath, ma attualmente non è supportato molto bene da tutti i browser.

Ecco come aumentare le prestazioni dei tuoi selettori jQuery:

Aggiungerò una nota che nel 99% delle app Web, anche nelle app pesanti Ajax, la velocità di connessione e la risposta del server Web determineranno le prestazioni della tua app anziché il Javascript.Non sto dicendo che dovresti scrivere codice intenzionalmente lento o che in generale essere consapevole di quali cose potrebbero essere più veloci di altre non va bene.

Ma mi chiedo se stai cercando di risolvere un problema che ancora non esiste, o anche se stai ottimizzando qualcosa che potrebbe modifica nel prossimo futuro (ad esempio, se più persone inizieranno a utilizzare un browser che supporti getElementsByClassName() a cui si fa riferimento in precedenza), rallentando l'esecuzione del codice ottimizzato.

Un altro posto in cui cercare informazioni sulle prestazioni è la pagina Analisi delle prestazioni dei selettori di Hugo Vidal Teixeira.

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

Ciò fornisce una buona riduzione delle velocità per il selettore per ID, il selettore per classe e il nome del tag che prefissa il selettore.

I selettori più veloci per ID sono stati:$("#id")

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

Quindi il prefisso per tag è stato utile solo quando si seleziona per classe!

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

In ogni caso non me ne preoccuperei troppo a meno che tu non stia eseguendo quel selettore migliaia di volte al secondo.

Se sei veramente preoccupato, prova a fare qualche benchmark e vedi quale è più veloce.

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

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

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

Molto utile!

UN ottimo consiglio da una domanda che ho posto:Utilizzo selettori CSS standard ove possibile.Ciò consente a jQuery di utilizzare il file API dei selettori.Secondo test eseguiti da John Resig, ciò si traduce in prestazioni quasi native per i selettori.Funzioni come :has() E :contains() dovrebbe essere evitato.

Dalla mia ricerca il supporto per l'API Selectors è stato introdotto con jQuery 1.2.7, Firefox 3.1, IE 8, Opera 10, Safari 3.1.

Se non sbaglio, anche jQuery è un motore bottom up.Questo significa $('#foo bar div') è molto più lento di $('bar div #foo').Per esempio, $('#foo a') passerà attraverso tutto il a elementi sulla pagina e vedere se hanno un antenato di #foo, il che rende questo selettore estremamente inefficiente.

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

Credo che selezionare prima per ID sia sempre più veloce:

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

dovrebbe essere più veloce di

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

Tuttavia, mi chiedo quanto sia utile il concatenamento quando si inizia con l'ID?È questo

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

più veloce di così?

$("#myform th").css("color","red");
$("#myform td").css("color","blue");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top