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
- Performances de
div.innerHTML
etdiv.outerHTML
multipliées par 2,4 (V8, JavaScriptCore) - Performances de
div.innerText
et dediv.outerText
dans Chromium/Mac par 4 fois (V8/Mac) - Amélioration des accès aux propriétés CSS de 35% (JavaScriptCore)
- Performances
div.classList
,div.dataset
etdiv.attributes
améliorées jusqu'à 10,9x (V8) - Performances
div.firstElementChild
,lastElementChild
,previousElementSibling
etnextElementSibling
améliorées de 7,1 x (V8) - L'accès aux attributs DOM V8 a été amélioré de 4 à 5% (V8)
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 formeinnerHTML
.
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.