Frage

Ich suche nach einer Möglichkeit, die Selektorleistung eines jQuery-Aufrufs zu verbessern.Konkret Dinge wie diese:

Ist $("div.myclass") schneller als $(".myclass")

Ich würde denken, dass es so sein könnte, aber ich weiß nicht, ob jQuery intelligent genug ist, um die Suche zuerst nach Tag-Namen usw. einzuschränken.Hat jemand eine Idee, wie man eine jQuery-Selektorzeichenfolge für die beste Leistung formulieren kann?

War es hilfreich?

Lösung

Es besteht kein Zweifel, dass Das Filtern nach Tag-Namen zuerst ist viel schneller als nach Klassennamen zu filtern.

Dies wird der Fall sein, bis alle Browser getElementsByClassName nativ implementieren, wie dies bei getElementsByTagName der Fall ist.

Andere Tipps

In manchen Fällen können Sie eine Abfrage beschleunigen, indem Sie ihren Kontext einschränken.Wenn Sie über eine Elementreferenz verfügen, können Sie diese als zweites Argument übergeben, um den Umfang der Abfrage einzuschränken:

$(".myclass", a_DOM_element);

sollte schneller sein als

$(".myclass");

wenn Sie bereits ein_DOM_element haben und es deutlich kleiner als das gesamte Dokument ist.

Wie Reid oben sagte, arbeitet jQuery von unten nach oben.Obwohl

das bedeutet $('#foo bar div') ist viel langsamer als $('bar div #foo')

Das ist nicht der Punkt.Wenn du hättest #foo Sie würden im Selektor ohnehin nichts davor einfügen, da IDs eindeutig sein müssen.

Der Punkt ist:

  • Wenn Sie eine Unterauswahl eines Elements mit einer ID vornehmen, wählen Sie zuerst das Letztere aus und verwenden Sie es dann .find, .children usw.: $('#foo').find('div')
  • Ihr ganz linker (erster) Teil des Selektors dürfen Die Skalierung auf den ganz rechten (letzten) Teil ist weniger effizient sollen Seien Sie am effizientesten. Wenn Sie also keinen Ausweis haben, stellen Sie sicher, dass Sie danach suchen $('div.common[slow*=Search] input.rare') statt $('div.rare input.common[name*=slowSearch]') - Da dies nicht immer zutrifft, stellen Sie sicher, dass Sie die Auswahlreihenfolge durch entsprechende Aufteilung erzwingen.

Um vollständig zu verstehen, was schneller ist, müssen Sie verstehen, wie der CSS-Parser funktioniert.

Der von Ihnen übergebene Selektor wird mithilfe von RegExp in erkennbare Teile aufgeteilt und dann Stück für Stück verarbeitet.

Einige Selektoren wie ID und TagName verwenden die native Implementierung des Browsers, die schneller ist.Während andere wie Klassen und Attribute separat programmiert werden und daher viel langsamer sind, müssen ausgewählte Elemente durchlaufen und jeder einzelne Klassenname überprüft werden.

Also ja, um Ihre Frage zu beantworten:

$('tag.class') ist schneller als nur $('.class').Warum?Im ersten Fall verwendet jQuery die native Browser-Implementierung, um die Auswahl auf die benötigten Elemente zu filtern.Erst dann wird die langsamere .class-Implementierung gestartet, die auf das herunterfiltert, was Sie angefordert haben.

Im zweiten Fall verwendet jQuery seine Methode, um jedes einzelne Element durch Ergreifen der Klasse zu filtern.

Dies verbreitet sich weiter als jQuery, da alle Javascript-Bibliotheken darauf basieren.Die einzige andere Option ist die Verwendung von xPath, diese wird jedoch derzeit nicht von allen Browsern sehr gut unterstützt.

So steigern Sie die Leistung Ihrer jQuery-Selektoren:

  • Wann immer möglich, nach #id auswählen (Leistungstestergebnisse ~250 schneller)
  • Geben Sie den Umfang Ihrer Auswahl an ($('.select', this))

Ich füge einen Hinweis hinzu, dass bei 99 % der Web-Apps, sogar bei Ajax-lastigen Apps, die Verbindungsgeschwindigkeit und die Reaktion des Webservers die Leistung Ihrer App bestimmen und nicht das Javascript.Ich sage nicht, dass Sie absichtlich langsamen Code schreiben sollten oder dass es nicht gut ist, sich generell darüber im Klaren zu sein, welche Dinge wahrscheinlich schneller sind als andere.

Aber ich frage mich, ob Sie versuchen, ein Problem zu lösen, das noch nicht wirklich existiert, oder ob Sie sogar für etwas optimieren, das möglicherweise existiert ändern in naher Zukunft (z. B. wenn mehr Menschen anfangen, einen Browser zu verwenden, der unterstützt). getElementsByClassName() Funktion, auf die zuvor verwiesen wurde), wodurch Ihr optimierter Code tatsächlich langsamer ausgeführt wird.

Ein weiterer Ort, an dem Sie nach Leistungsinformationen suchen können, ist die Seite „Leistungsanalyse von Selektoren“ von Hugo Vidal Teixeira.

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

Dies ergibt einen guten Überblick über die Geschwindigkeiten für Selektor nach ID, Selektor nach Klasse und Selektor mit vorangestelltem Tag-Namen.

Die schnellsten Selektoren nach ID waren:$("#id")

Der schnellste Selektor nach Klasse war:$('tag.class')

Das Präfixieren nach Tag hat also nur bei der Auswahl nach Klasse geholfen!

Ich war auf einigen jQuery-Mailinglisten und nach dem, was ich dort gelesen habe, filtern sie höchstwahrscheinlich nach Tag-Namen und dann nach Klassennamen (oder umgekehrt, wenn es schneller war).Sie sind besessen von Geschwindigkeit und würden alles tun, um ein bisschen Leistung zu erzielen.

Ich würde mir darüber sowieso keine allzu großen Sorgen machen, es sei denn, Sie führen diesen Selektor tausende Male pro Sekunde aus.

Wenn Sie wirklich besorgt sind, versuchen Sie es mit einem Benchmarking und finden Sie heraus, welches schneller ist.

Erwägen Sie die Verwendung der Sequentially-Bibliothek von Oliver Steele, um Methoden über einen bestimmten Zeitraum statt alle auf einmal aufzurufen.

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

Mit der Methode „eventually“ können Sie eine Methode nach einer bestimmten Zeitspanne nach dem ersten Aufruf aufrufen.Mit der Methode „sequentiell“ können Sie mehrere Aufgaben über einen bestimmten Zeitraum in eine Warteschlange stellen.

Sehr hilfreich!

A toller Tipp aus einer Frage, die ich gestellt habe:Verwenden Standard-CSS-Selektoren woimmer möglich.Dadurch kann jQuery das verwenden Selektoren-API.Entsprechend Tests durchgeführt von John Resig, Dies führt zu einer nahezu nativen Leistung für Selektoren.Funktionen wie :has() Und :contains() sollte vermieden werden.

Aus meiner Forschung geht hervor, dass die Unterstützung für die Selectors-API mit jQuery 1.2.7, Firefox 3.1, IE 8, Opera 10 und Safari 3.1 eingeführt wurde.

Wenn ich mich nicht irre, ist jQuery auch eine Bottom-up-Engine.Das bedeutet $('#foo bar div') ist viel langsamer als $('bar div #foo').Zum Beispiel, $('#foo a') werde alles durchgehen a Elemente auf der Seite und sehen Sie, ob sie einen Vorfahren von haben #foo, was diesen Selektor äußerst ineffizient macht.

Resig hat möglicherweise bereits für dieses Szenario optimiert (es würde mich nicht überraschen, wenn er das täte – ich glaube, dass er das in seiner Sizzle-Engine getan hat, bin mir aber nicht hundertprozentig sicher).

Ich glaube, dass die Auswahl zuerst nach ID immer schneller ist:

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

sollte schneller sein als

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

Allerdings frage ich mich, wie viel Verkettung beim Start mit der ID hilft?Ist das

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

Gibt es etwas schnelleres?

$("#myform th").css("color","red");
$("#myform td").css("color","blue");
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top