Wir freuen uns sehr, dass einige gängige DOM-Vorgänge jetzt viel schneller sind. Die Änderungen wurden auf WebKit-Ebene vorgenommen und steigern die Leistung sowohl in Safari (JavaScriptCore) als auch in Chrome (V8).
Der Chrome-Entwickler Kentaro Hara hat sieben Codeoptimierungen in WebKit vorgenommen. Unten sehen Sie die Ergebnisse, die zeigen, wie viel schneller der JavaScript-DOM-Zugriff geworden ist:
Leistungssteigerungen für das DOM – Zusammenfassung
div.innerHTML
unddiv.outerHTML
: Leistung um 2,4 mal verbessert (V8, JavaScriptCore)div.innerText
unddiv.outerText
in Chromium/Mac um das Vierfache (V8/Mac)- Zugriffe auf CSS-Properties um 35% verbessert (JavaScriptCore)
div.classList
,div.dataset
unddiv.attributes
: bis zu 10,9-fache Leistungssteigerung (V8)div.firstElementChild
,lastElementChild
,previousElementSibling
undnextElementSibling
: 7,1-fache Leistungssteigerung (V8)- Der Zugriff auf V8-DOM-Attribute wurde um 4 bis 5% verbessert (V8)
Im Folgenden erläutert Kentaro Hara einige der von ihm erstellten Patches. Die Links führen zu WebKit-Fehlern mit Testfällen, die Sie selbst ausprobieren können. Die Änderungen wurden zwischen WebKit r109829 und r111133 vorgenommen: Chrome 17 enthält sie nicht, Chrome 19 hingegen schon.
Leistung von div.innerHTML
und div.outerHTML
um das 2,4-fache verbessert (V8, JavaScriptCore)
Bisheriges Verhalten in WebKit:
- Erstellen Sie für jedes Tag einen String.
- Fügen Sie
Vector<string>
einen erstellten String hinzu und parsen Sie den DOM-Baum. - Weisen Sie nach dem Parsen einen String zu, dessen Größe der Summe aller Strings in
Vector<string>
entspricht. - Verkettet alle Strings in
Vector<string>
und gibt sie alsinnerHTML
zurück.
Neues Verhalten in WebKit:
1. Weisen Sie einen String zu, z. B. „S“.
1. Konkatenieren Sie einen String für jedes Tag mit „S“ und parsen Sie den DOM-Baum schrittweise.
1. Gibt S als innerHTML
zurück.
Kurz gesagt: Anstatt viele Strings zu erstellen und dann zu verketten, erstellt der Patch einen String und hängt dann einfach inkrementell Strings an.
Leistung von div.innerText
und div.outerText
in Chromium/Mac um das Vierfache verbessert (V8/Mac)
Mit dem Patch wurde nur die anfängliche Puffergröße für das Erstellen von innerText
geändert. Durch die Änderung der anfänglichen Puffergröße von 2^16 auf 2^15 konnte die Leistung von Chromium/Mac vervierfacht werden. Dieser Unterschied hängt vom zugrunde liegenden Malloc-System ab.
Leistung der Zugriffe auf CSS-Properties in JavaScriptCore um 35%verbessert
Ein CSS-Eigenschaftsstring (z.B. .fontWeight
, .backgroundColor
) wird in WebKit in eine Ganzzahl-ID umgewandelt. Diese Konvertierung ist sehr umfangreich. Der Patch speichert die Conversion-Ergebnisse in einer Map (d.h. ein Property-String = eine Ganzzahl-ID), damit die Conversion nicht mehrmals durchgeführt wird.
Wie funktionieren die Tests?
Sie messen die Zeit der Zugriffe auf die Property. Bei innerHTML
(dem Leistungstest unter bugs.webkit.org/show_bug.cgi?id=81214) wird nur die Zeit gemessen, die für die Ausführung des folgenden Codes benötigt wird:
for (var i = 0; i < 1000000; i++)
document.body.innerHTML;
Für den Leistungstest wird ein großer Text verwendet, der aus der HTML-Spezifikation kopiert wurde.
Ähnlich wird beim Test für CSS-Property-Zugriffe die Zeit für den folgenden Code gemessen:
var spanStyle = span.style;
for (var i = 0; i < 1000000; i++) {
spanStyle.invalidFontWeight;
spanStyle.invalidColor;
spanStyle.invalidBackgroundColor;
spanStyle.invalidDisplay;
}
Die gute Nachricht ist, dass Kentaro Hara davon ausgeht, dass weitere Leistungsverbesserungen für andere wichtige DOM-Attribute und ‑Methoden möglich sind.
Auf gehts!
Ein großes Lob an Haraken und das gesamte Team.