jQuery-Selektor Leistung
-
05-07-2019 - |
Frage
Ich habe starke Unterschiede in der Leistung je nachdem, wie ich meine Wähler äußern. Zum Beispiel, schauen Sie sich diese 2-Selektoren, die genau die gleichen Elemente auswählen:
A) someTableRow.find("td.someColumnClass").find("span.editMode").find("input")
B) someTableRow.find("td.someColumnClass span.editMode input")
würde ich erwarten) nach B, schneller zu sein, da es nur 1 Aufruf ist, aber in Wirklichkeit ist ich die Suche nach A) führt etwa 8-mal schneller. Ich habe keine Ahnung, warum jemand einen Einblick hat? Dank
Lösung
Sie verwenden mindestens jQuery 1.3 Vorausgesetzt (d.h. unter Zusatz von Sizzle), die Leistung, die Sie sehen, ist aufgrund der Änderung in dem das DOM durchlaufen wird. Von hier :
Bis einschließlich jQuery 1.2.6 der Selektor-Engine arbeitete in einem "Top-down" (Oder „links nach rechts“) Art und Weise. jQuery 1.3.x (dh Sizzle , die jQuery bettet) einen "bottom up" eingeführt (oder „Rechts nach links“) Ansatz zur Abfrage das DOM.
In Ihrem zweiten Beispiel ("td.someColumnClass span.editMode input"
), Sizzle effektiv tut dies:
- erhalten alle
input
Elemente innerhalbsomeTableRow
- für jedes
input
Element gefunden, durchqueren seine Vorfahren Baum fürspan
Elemente mitclass="editMode"
. Entferneninput
Elemente, die nicht über diese Vorfahren haben - für jedes
span.editMode
Element gefunden, durchqueren seine Vorfahren Baum fürtd
Elemente mitclass="someColumnClass"
. Entferneninput
Elemente, die nicht über diese Vorfahren haben
In Ihrem ersten Beispiel aber Ihre sind jeden Schritt explizit bei jedem Aufruf der Qualifikation einen Kontext zu find()
, zu definieren und durchqueren unten von dort aus. Sie sind die Durchsetzung der „Top-down“ -Ansatz. Er entspricht in einem Kontext, bei jedem Schritt zu übergeben, welches im allgemeinen ein Leistungsverstärker betrachtet:
$('input', $('span.editMode', $('td.someColumnClass', someTableRow)))
Andere Tipps
Da Sie den Kontext für die Suche reduzieren.
Im Fall B, es hat durch all DOM-Element zu suchen, um zu sehen, ob es die Kriterien erfüllt.
Im Fall A kann sich schnell entscheiden, alles zu ignorieren, die nicht „td.someColumnClass“ ist, dann ist es, dass die Teilmenge des DOM nehmen und alles ignorieren, die nicht in „span.editMode“ ist. So hat es eine viel kleinere Menge von Elementen durchsuchen zu finden „Input“ s jetzt.
A sind mehr Anrufe, aber einfacher. B ist ein Anruf, aber komplexer. In diesem Fall wiegt Außer die Komplexität des Anrufs stark die Menge der Anrufe.
Die Art und Weise JQuery Griffe selctors ist ein wenig anders zu CSS in meiner Erfahrung.
Die Reduzierung der Kontext auf die Suche wird der Schlüssel als Josh hingewiesen.
Ich finde mit den beiden Parameter Selektoren wirklich schnell
Wie vergleicht diese Geschwindigkeit weise?
Sie brauchen nicht alle Vars hier ist es nur klar zu machen, was ich tue.
var columnClasses = $('.someColumnClass');
var tableCell = $('td', columnclasses);
var editMode = $('.editmode', tableCell);
var spanInside = $('span', editMode);
var inputFinally = $('input', spanInside);
Güte,
Dan
Ich habe einige der Forschung auf jQuery Selector Leistung selbst. Ein großes Problem sind Lookups von Klassennamen auf Internet Explorer. IE doesnt Unterstützung getElementsByClassName - deshalb jQuery und anderen Frameworks „reimplementieren“ es in JavaScript, indem Sie durch alle DOM-Elemente iterieren. Überprüfen Sie die folgende Analyse Blog sich über jQuery Selector-Performance
Es ist ein wirklich interessanter Artikel über Selektor Leistung hier: http: // blogs .atlassian.com / Entwickler / 2009/08 / jquery_bondage.html
Darin zeigt der Autor eine „bind“ jQuery-Erweiterung, die zeigt, wie oft die Funktion ausgewertet wird.