Deutlicher Anstieg der DOM-Leistung – innerHTML von WebKit ist 240% schneller

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

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 als innerHTML 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.