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

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

Kentaro Hara, ingeniero de Chrome, realizó siete optimizaciones de código en WebKit. A continuación, se muestran los resultados, que demuestran lo mucho más rápido que se volvió el acceso al DOM de JavaScript:

Resumen de los aumentos de rendimiento del DOM

A continuación, Kentaro Hara brinda detalles sobre algunos de los parches que hizo. Los vínculos son a errores de WebKit con casos de prueba, para que puedas probarlos por tu cuenta. Los cambios se realizaron entre WebKit r109829 y r111133: Chrome 17 no los incluye, pero Chrome 19 sí.

Mejora el rendimiento de div.innerHTML y div.outerHTML en un 2.4 veces (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 cadena cuyo tamaño sea la suma de todas las cadenas en Vector<string>.
  • Concatena todas las cadenas en Vector<string> y devuélvelas como innerHTML.

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

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

Se mejoró el rendimiento de div.innerText y div.outerText en Chromium/Mac en un 400% (V8/Mac).

El parche solo cambió 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 4 veces. Esta diferencia depende del sistema malloc subyacente.

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

Una cadena de propiedades 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 las conversiones 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 la propiedad. En el caso de innerHTML (la prueba de rendimiento en bugs.webkit.org/show_bug.cgi?id=81214), la prueba solo mide el tiempo 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.

Del mismo modo, la prueba de accesos a propiedades 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 cree que se podrán realizar más mejoras de rendimiento para otros atributos y métodos importantes del DOM.

¡Adelante!

Felicitaciones a Haraken y al resto del equipo.