Amélioration significative des performances du DOM : innerHTML de WebKit est 240% plus rapide

Nous sommes très heureux de constater que certaines opérations DOM courantes viennent d'être accélérées. Ces modifications ont été apportées au niveau de WebKit et ont permis d'améliorer les performances de Safari (JavaScriptCore) et de Chrome (V8).

L'ingénieur Chrome Kentaro Hara a effectué sept optimisations de code dans WebKit. Voici les résultats qui montrent à quel point l'accès DOM JavaScript est devenu beaucoup plus rapide:

Récapitulatif des optimisations des performances DOM

Ci-dessous, Kentaro Hara donne des détails sur certains des correctifs qu'il a faits. Les liens renvoient vers des bugs WebKit associés à des scénarios de test, afin que vous puissiez tester les tests par vous-même. Les modifications ont été apportées entre WebKit r109829 et r111133: Chrome 17 ne les inclut pas, contrairement à Chrome 19.

Multiplication par 2,4 des performances de div.innerHTML et div.outerHTML (V8, JavaScriptCore)

Comportement précédent dans WebKit:

  • Créez une chaîne pour chaque tag.
  • Ajoutez une chaîne créée à Vector<string>, en analysant l'arborescence DOM.
  • Après l'analyse, allouez une chaîne dont la taille correspond à la somme de toutes les chaînes de Vector<string>.
  • Concaténez toutes les chaînes dans Vector<string> et renvoyez-la sous la forme innerHTML.

Nouveau comportement dans WebKit : 1. Allouez une chaîne, dites S. 1. Concaténez une chaîne pour chaque balise en S, en analysant progressivement l'arborescence DOM. 1. Renvoie S en tant que innerHTML.

En bref, au lieu de créer un grand nombre de chaînes et de les concaténer, la commande patch crée une chaîne, puis ajoute simplement des chaînes de manière incrémentielle.

Multiplication par quatre des performances de div.innerText et div.outerText dans Chromium/Mac (V8/Mac)

Le correctif vient de modifier la taille de la mémoire tampon initiale pour la création de innerText. Le fait de faire passer la taille de la mémoire tampon initiale de 2^16 à 2^15 a permis d'améliorer les performances de Chromium/Mac par quatre. Cette différence dépend du système malloc sous-jacent.

Amélioration de 35%des performances des accès aux propriétés CSS dans JavaScriptCore

Une chaîne de propriété CSS (par exemple, .fontWeight ou .backgroundColor) est convertie en ID entier dans WebKit. Cette conversion est importante. Le correctif met en cache les résultats de la conversion dans une map (c'est-à-dire une chaîne de propriété => un ID entier), afin que la conversion ne soit pas effectuée plusieurs fois.

Comment fonctionnent les tests ?

Elles mesurent le temps d'accès aux propriétés. Dans le cas d'une erreur innerHTML (le test de performances dans bugs.webkit.org/show_bug.cgi?id=81214), le test mesure simplement le temps nécessaire à l'exécution du code suivant:

for (var i = 0; i < 1000000; i++)
    document.body.innerHTML;

Le test de performances utilise un corps volumineux copié à partir de la spécification HTML.

De même, le test des accès aux propriétés CSS mesure la durée du code suivant:

var spanStyle = span.style;
for (var i = 0; i < 1000000; i++) {
    spanStyle.invalidFontWeight;
    spanStyle.invalidColor;
    spanStyle.invalidBackgroundColor;
    spanStyle.invalidDisplay;
}

La bonne nouvelle, c'est que Kentaro Hara estime que d'autres attributs et méthodes DOM importants pourront améliorer les performances.

Allez-y !

Félicitations à Haraken et au reste de l'équipe.