Gran mejora en el rendimiento del DOM: WebKit's internalHTML es un 240% más rápido

Nos complace ver que la velocidad de algunas operaciones comunes del DOM aumentó vertiginosamente. Los cambios se realizaron a nivel de WebKit, lo que mejoró el rendimiento de Safari (JavaScriptCore) y Chrome (V8).

El ingeniero de Chrome Kentaro Hara realizó siete optimizaciones de código en WebKit. A continuación, se muestran los resultados que muestran cuánto más rápido se ha vuelto el acceso al DOM en JavaScript:

Resumen sobre el rendimiento del DOM

A continuación, Kentaro Hara da detalles sobre algunos de los parches que hizo. Los vínculos son a errores de WebKit con casos de prueba, para que puedas realizar las pruebas tú mismo. Se realizaron cambios entre WebKit r109829 y r111133: Chrome 17 no los incluye, mientras que Chrome 19 sí.

Mejora 2.4 veces el rendimiento de div.innerHTML y div.outerHTML (V8, JavaScriptCore)

Comportamiento anterior en WebKit:

  • Crea una cadena para cada etiqueta.
  • Agrega una cadena creada a Vector<string> y analiza el árbol del DOM.
  • Después del análisis, asigna una string cuyo tamaño sea la suma de todas las strings en Vector<string>.
  • Concatena todas las strings en Vector<string> y muéstrala como innerHTML.

Nuevo comportamiento en WebKit: 1. Asigna una cadena, por ejemplo, S. 1. Concatena una cadena para cada etiqueta en S y analiza el árbol del DOM de forma incremental. 1. Muestra S como innerHTML.

En pocas palabras, en lugar de crear muchas cadenas y luego concatenarlas, el parche crea una cadena y, luego, las agrega de forma incremental.

Se mejoró el rendimiento de div.innerText y div.outerText en Chromium/Mac por 4x (V8/Mac)

El parche acaba de cambiar el tamaño del búfer inicial para crear innerText. Cambiar el tamaño del búfer inicial de 2^16 a 2^15 mejoró el rendimiento de Chromium/Mac en 4 veces. Esta diferencia depende del sistema malloc subyacente.

Mejora en un 35%el rendimiento de los accesos a las propiedades de CSS en JavaScriptCore

Una cadena de propiedad de CSS (p.ej., .fontWeight, .backgroundColor) se convierte en un ID de número entero en WebKit. Esta conversión es pesada. El parche almacena en caché los resultados de la conversión en un mapa (es decir, una cadena de propiedad => un ID de número entero), para que la conversión no se realice varias veces.

¿Cómo funcionan las pruebas?

Miden el tiempo de los accesos a las propiedades. En el caso de innerHTML (la prueba de rendimiento en bugs.webkit.org/show_bug.cgi?id=81214), la prueba solo mide el tiempo necesario para ejecutar el siguiente código:

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

La prueba de rendimiento usa un cuerpo grande copiado de la especificación HTML.

De manera similar, la prueba de accesos a la propiedad de CSS mide el tiempo del siguiente código:

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

La buena noticia es que Kentaro Hara considera que es posible realizar más mejoras en el rendimiento para otros atributos y métodos importantes del DOM.

¡Adelante!

Felicitaciones a Haraken y al resto del equipo.