Siamo molto felici di vedere che la velocità di alcune operazioni DOM comuni è aumentata vertiginosamente. Le modifiche sono state apportate a livello di WebKit, migliorando le prestazioni sia di Safari (JavaScriptCore) che di Chrome (V8).
Il Chrome Engineer Kentaro Hara ha apportato sette ottimizzazioni del codice in WebKit; di seguito sono riportati i risultati, che mostrano quanto è diventato più veloce l'accesso DOM JavaScript:
Riepilogo aumenti delle prestazioni del DOM
- Le prestazioni di
div.innerHTML
ediv.outerHTML
sono migliorate di 2,4 volte (V8, JavaScriptCore) - Prestazioni di
div.innerText
ediv.outerText
su Chromium/Mac di 4x (V8/Mac) - Gli accessi alle proprietà CSS sono migliorati del 35% (JavaScriptCore)
- Prestazioni di
div.classList
,div.dataset
ediv.attributes
migliorate di fino a 10,9x (V8) - Prestazioni di
div.firstElementChild
,lastElementChild
,previousElementSibling
enextElementSibling
migliorate di 7,1 volte (V8) - Accesso agli attributi DOM V8 migliorato del 4 ~ 5% (V8)
Di seguito, Kentaro Hara fornisce i dettagli su alcune delle patch che ha realizzato. I link rimandano ai bug di WebKit con scenari di test, in modo che tu possa provare i test in autonomia. Le modifiche sono state apportate tra WebKit r109829 e r111133: Chrome 17 non le include, Chrome 19 sì.
Miglioramento delle prestazioni di div.innerHTML
e div.outerHTML
di 2,4 volte (V8, JavaScriptCore)
Comportamento precedente in WebKit:
- Crea una stringa per ogni tag.
- Aggiungi una stringa creata a
Vector<string>
, analizzando l'albero DOM. - Dopo l'analisi, alloca una stringa la cui dimensione corrisponde alla somma di tutte le stringhe in
Vector<string>
. - Concatena tutte le stringhe in
Vector<string>
e restituiscile comeinnerHTML
.
Nuovo comportamento in WebKit:
1. Alloca una stringa, pronuncia S.
1. Concatena una stringa per ogni tag a S, analizzando in modo incrementale l'albero DOM.
1. Restituisci S come innerHTML
.
In poche parole, invece di creare tante stringhe e poi concatenarle, la patch crea una stringa e poi le aggiunge semplicemente in modo incrementale.
Miglioramento di 4 volte le prestazioni di div.innerText
e div.outerText
in Chromium/Mac (V8/Mac)
La patch ha appena modificato la dimensione del buffer iniziale per la creazione di innerText
. La modifica della dimensione del buffer iniziale da 2^16 a 2^15 ha migliorato le prestazioni di Chromium/Mac di 4 volte. Questa differenza dipende dal sistema Malloc sottostante.
Miglioramento del 35%delle prestazioni degli accessi alle proprietà CSS in JavaScriptCore
Una stringa di proprietà CSS (ad es. .fontWeight
, .backgroundColor
) viene convertita in un ID numero intero in WebKit. Il volume di questa conversione è elevato. La patch memorizza nella cache i risultati della conversione in una mappa (ovvero una stringa di proprietà => un ID intero), in modo che la conversione non venga effettuata più volte.
Come funzionano i test?
Misurano l'ora degli accessi alle proprietà. Nel caso di innerHTML
(il test delle prestazioni in bugs.webkit.org/show_bug.cgi?id=81214), il test misura solo il tempo necessario per eseguire il codice seguente:
for (var i = 0; i < 1000000; i++)
document.body.innerHTML;
Il test delle prestazioni utilizza un corpo di grandi dimensioni copiato dalla specifica HTML.
Allo stesso modo, il test di accesso alla proprietà CSS misura l'ora del seguente codice:
var spanStyle = span.style;
for (var i = 0; i < 1000000; i++) {
spanStyle.invalidFontWeight;
spanStyle.invalidColor;
spanStyle.invalidBackgroundColor;
spanStyle.invalidDisplay;
}
La buona notizia è che Kentaro Hara ritiene che saranno possibili ulteriori miglioramenti delle prestazioni per altri importanti attributi e metodi del DOM.
Dai un'occhiata!
Complimenti a Haraken e al resto del team.