Nous sommes très heureux de constater que la vitesse de certaines opérations DOM courantes a explosé. Les modifications ont été apportées au niveau de WebKit, ce qui a amélioré les performances de Safari (JavaScriptCore) et de Chrome (V8).
L'ingénieur Chrome Kentaro Hara a effectué sept optimisations de code dans WebKit. Vous trouverez ci-dessous les résultats, qui montrent à quel point l'accès au DOM JavaScript est devenu plus rapide:
Résumé des améliorations des performances du DOM
- Amélioration des performances de
div.innerHTML
etdiv.outerHTML
de 2,4 fois (V8, JavaScriptCore) - Amélioration des performances de
div.innerText
etdiv.outerText
dans Chromium/Mac de 4 fois (V8/Mac) - Amélioration de 35% des accès aux propriétés CSS (JavaScriptCore)
- Amélioration des performances de
div.classList
,div.dataset
etdiv.attributes
de jusqu'à 10,9 fois (V8) - Amélioration des performances de 7,1 fois (V8) pour
div.firstElementChild
,lastElementChild
,previousElementSibling
etnextElementSibling
- Amélioration de l'accès aux attributs DOM V8 de 4 à 5% (V8)
Vous trouverez ci-dessous des informations sur certains des correctifs qu'il a apportés. Les liens renvoient à des bugs WebKit avec des scénarios de test, ce qui vous permet de les tester vous-même. Les modifications ont été apportées entre les versions WebKit r109829 et r111133: Chrome 17 ne les inclut pas, mais Chrome 19 le fait.
Amélioration des performances de div.innerHTML
et div.outerHTML
de 2,4 fois (V8, JavaScriptCore)
Comportement précédent dans WebKit:
- Créez une chaîne pour chaque balise.
- 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 l'
Vector<string>
. - Concatène toutes les chaînes de
Vector<string>
et les renvoie sous la formeinnerHTML
.
Nouveau comportement dans WebKit :
1. Allouez une chaîne, par exemple S.
1. Concatenate une chaîne pour chaque balise à S, en analysant de manière incrémentielle l'arborescence DOM.
1. Renvoyez S en tant que innerHTML
.
En résumé, au lieu de créer de nombreuses chaînes et de les concatenar, le correctif crée une chaîne, puis ajoute simplement des chaînes de manière incrémentielle.
Amélioration des performances de div.innerText
et div.outerText
dans Chromium/Mac de 4 fois (V8/Mac)
Le correctif a simplement modifié la taille de la mémoire tampon initiale pour la création de innerText
. En passant de 2^16 à 2^15, la taille de la mémoire tampon initiale a quadruplé les performances de Chromium/Mac. Cette différence dépend du système malloc sous-jacent.
Amélioration des performances des accès aux propriétés CSS dans JavaScriptCore de 35%
Une chaîne de propriété CSS (par exemple, .fontWeight
, .backgroundColor
) est convertie en ID entier dans WebKit. Cette conversion est lourde. Le correctif met en cache les résultats de la conversion dans une carte (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 l'heure des accès à la propriété. Dans le cas de innerHTML
(test de performances dans bugs.webkit.org/show_bug.cgi?id=81214), le test ne mesure que le temps d'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 le temps 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 est que Kentaro Hara pense que d'autres améliorations de performances seront possibles pour d'autres attributs et méthodes DOM importants.
Allez-y !
Bravo à Haraken et au reste de l'équipe.