Wir freuen uns sehr, dass einige gängige DOM-Vorgänge jetzt viel schneller ausgeführt werden. Die Änderungen wurden auf WebKit-Ebene vorgenommen und haben die Leistung sowohl für Safari (JavaScriptCore) als auch für Chrome (V8) gesteigert.
Der Chrome-Entwickler Kentaro Hara hat sieben Codeoptimierungen in WebKit vorgenommen. Die Ergebnisse sind unten zu sehen. Sie zeigen, wie viel schneller der JavaScript-DOM-Zugriff geworden ist:
Zusammenfassung der DOM-Leistungssteigerungen
div.innerHTML
unddiv.outerHTML
Leistung um das 2,4‑Fache verbessert (V8, JavaScriptCore)div.innerText
- unddiv.outerText
-Leistung in Chromium/Mac um das Vierfache (V8/Mac)- Verbesserter Zugriff auf CSS-Properties um 35% (JavaScriptCore)
div.classList
,div.dataset
unddiv.attributes
wurden um bis zu 10,9‑mal verbessert (V8)div.firstElementChild
,lastElementChild
,previousElementSibling
undnextElementSibling
haben sich um das 7,1-Fache verbessert (V8)- Verbesserter Zugriff auf V8‑DOM-Attribute um 4 bis 5% (V8)
Im Folgenden beschreibt Kentaro Hara einige der von ihm vorgenommenen Änderungen. Die Links führen zu WebKit-Bugs mit Testläufen, sodass Sie die Tests selbst ausprobieren können. Die Änderungen wurden zwischen WebKit r109829 und r111133 vorgenommen: Chrome 17 enthält sie nicht, Chrome 19 schon.
Leistung von div.innerHTML
und div.outerHTML
um das 2,4-Fache verbessern (V8, JavaScriptCore)
Bisheriges Verhalten in WebKit:
- Erstellen Sie für jedes Tag einen String.
- Hängen Sie einen erstellten String an
Vector<string>
an 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 das Ergebnis alsinnerHTML
zurück.
Neues Verhalten in WebKit:
1. Weisen Sie einen String zu, z. B. S.
1. Verketten Sie für jedes Tag einen String mit S und parsen Sie den DOM-Baum inkrementell.
1. Gibt S als innerHTML
zurück.
Kurz gesagt: Anstatt viele Strings zu erstellen und sie dann zu verketten, wird mit dem Patch ein String erstellt und dann werden Strings inkrementell angehängt.
Leistung von div.innerText
und div.outerText
in Chromium/Mac um das Vierfache verbessern (V8/Mac)
Durch den Patch wurde nur die anfängliche Puffergröße für das Erstellen von innerText
geändert. Durch Ändern der anfänglichen Puffergröße von 2^16 auf 2^15 wurde die Leistung von Chromium/Mac um das Vierfache verbessert. Dieser Unterschied hängt vom zugrunde liegenden malloc-System ab.
Leistung von CSS-Property-Zugriffen in JavaScriptCore um 35%verbessert
Eine CSS-Property-String (z.B. .fontWeight
, .backgroundColor
) wird in WebKit in eine Ganzzahl-ID umgewandelt. Diese Konvertierung ist aufwendig. Der Patch speichert die Conversion-Ergebnisse in einer Map (d.h. einem Property-String => einer Ganzzahl-ID), damit die Conversion nicht mehrmals durchgeführt wird.
Wie funktionieren die Tests?
Sie messen die Zeit von Property-Zugriffen. Im Fall von innerHTML
(dem Leistungstest in 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 Textkörper verwendet, der aus der HTML-Spezifikation kopiert wurde.
Entsprechend wird beim Test für den Zugriff auf CSS-Eigenschaften 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;
}
Kentaro Hara ist jedoch zuversichtlich, dass sich die Leistung anderer wichtiger DOM-Attribute und ‑Methoden noch weiter verbessern lässt.
Los gehts!
Ein großes Lob an Haraken und das gesamte Team.