Introducción
Si eres de las personas que se mantienen al tanto de temas como cómo funcionan los navegadores, ya sabes que, últimamente, se publicaron algunos artículos increíbles que detallan la operación del renderizador/compuesto acelerado por GPU de Chrome. En primer lugar, Renderización acelerada en Chrome: el modelo de capas es una excelente introducción a cómo Chrome usa el concepto de capas para dibujar su página. Para un análisis más detallado, en Compilación acelerada por GPU en Chrome se explica cómo Chrome usa estas capas junto con la GPU para renderizar tu página.
La pregunta filosófica
Después de pasar mucho tiempo escribiendo rasterizadores de software para fines en 3D, me di cuenta de que algunas propiedades de CSS deberían tener un rendimiento variado cuando se dibuja la página. Por ejemplo, rasterizar una imagen pequeña en la pantalla es una operación algorítmica completamente diferente a dibujar una sombra en una forma arbitraria. Por lo tanto, la pregunta se convirtió en: ¿Cómo afectan las diferentes propiedades CSS al peso de renderización de tu página?
Mi objetivo era categorizar un gran conjunto de propiedades o valores de CSS según sus tiempos de pintura para que podamos comprender qué tipos de propiedades de CSS tienen un mejor rendimiento que otros. Para ello, escribí una automatización con cinta adhesiva y chicle para intentar agregar visibilidad numérica a los tiempos de pintura del CSS, que funcionó de la siguiente manera:
- Genera un paquete de páginas HTML individuales, cada una con un solo elemento DOM y alguna permutación de propiedades CSS adjuntas.
- Ejecuta una secuencia de comandos de automatización que, para cada página, haga lo siguiente:
- Iniciar Chrome
- Carga una página
- Produce una imagen de Skia para la página.
- Ejecuta cada imagen de Skia tomada a través de la comparativa de Skia para obtener los tiempos
- Elimina todos los tiempos y admira los números. (Esta parte es importante…)
Con esta configuración, generamos un paquete de páginas HTML, en el que cada página contiene una permutación única de propiedades y valores de CSS. Por ejemplo, estos son dos archivos HTML:
<style>
#example1 {
background: url(foo.png) top left / 50% 60%;
padding: 20px;
margin-top: 10px;
margin-right: 20px;
text-align: center;
}
</style>
<div id="example1">WOAH</div>
Y otro, que es más complejo
<style>
#example1 {
background-color:#eee;
box-shadow: 1px 2px 3px 4px black;
border-radius: 50%;
background: radial-gradient(circle closest-corner, white, black);
padding: 20px;
margin-top: 10px;
margin-right: 20px;
text-align: center;
}
</style>
<div id="example1">WOAH</div>
A continuación, como una variante del último ejemplo, en la que solo cambiamos el valor de gradiente radial:
<style>
#example1
{
background-color:#eee;
box-shadow: 1px 2px 3px 4px black;
border-radius: 50%;
background: radial-gradient(farthest-side, white, black);
padding: 20px;
margin-top: 10px;
margin-right: 20px;
text-align: center;
}
</style>
<div id="example1" style="padding: 20px; margin-top: 10px;margin-right: 20px; text-align: center;">WOAH</div>
Luego, cada página se carga en una instancia nueva de Chrome (para garantizar que los tiempos no se vean afectados por estados inactivos en las cargas de página) y se toma una imagen de Skia (*.SKP) para evaluar qué comandos de Skia se usan para pintar la página. Una vez que se generan los archivos SKP para cada archivo HTML, ejecutamos otro lote para enviar los archivos *.SKP a través de la aplicación de comparativa de Skia (compilada a partir del código fuente de Skia), que muestra el tiempo promedio que se tarda en renderizar esa página.
Cómo evaluar los datos
A partir de esto, ahora tenemos la capacidad aproximada de graficar cuánto tarda en pintarse un conjunto de propiedades de CSS. O mejor dicho, podemos comenzar a clasificar las propiedades de CSS según su rendimiento de pintura. Este es un gráfico grande tomado con la versión beta de Chrome 27 que muestra todo el conjunto completo de datos de tiempo de este proceso. Ten en cuenta que todos los datos están sujetos a cambios a medida que Chrome se vuelve más rápido con el tiempo.
Cada barra vertical representa el tiempo de pintura de una página con una sola combinación de propiedades CSS (magnificada por 100 veces; el valor de escala real de este gráfico es de 0.156 ms). Hay muchas líneas bonitas, pero en este formato son bastante inútiles. Necesitamos hacer un poco de minería de datos para encontrar tendencias útiles.
En primer lugar, encontramos pruebas de que algunas propiedades CSS son más costosas de renderizar que otras. Por ejemplo, dibujar una sombra en un elemento DOM implica una operación de varios pases con splines y otros tipos de elementos desagradables, a diferencia de la opacidad, que debería ser más fácil de renderizar.
En segundo lugar, y lo más interesante, las combinaciones de propiedades CSS pueden tener un tiempo de pintura mayor que la suma de sus partes. Desde la perspectiva de un observador, esto es un poco extraño, ya que esperaríamos que A+B = C, no 2.2C. Por ejemplo, agrega box-shadow
y border-radius-stroke
:
Lo que es realmente interesante de esto es que no se trata solo de la propiedad box-shadow
, sino de esa permutación de valor específica. Por ejemplo, a continuación, se muestra una agrupación de box-shadow : 50%
y border-radius
con variaciones de valor.
Si observas los datos, verás que esto ocurre durante un tiempo. Hay muchas combinaciones extrañas, y mi suite de pruebas apenas las toca. Aún hay muchas pruebas y combinaciones que podrían generar resultados interesantes.
Cómo encontrar el peso de renderización de tu página
Con la capacidad de hacer un seguimiento de los tiempos de renderización de cada elemento de tu página, los desarrolladores pueden comenzar a evaluar el peso de renderización de la página y cómo afecta la capacidad de respuesta de tu sitio. A continuación, se incluyen algunas sugerencias para comenzar.
- Usa el modo de pintura continua de Chrome en Chrome DevTools para comprender qué propiedades de CSS te están costando.
- Incorpora revisiones de CSS en tu proceso de revisión de código existente para detectar problemas de rendimiento. Busca lugares en tu CSS en los que uses elementos que se sepan que son más costosos, como gradientes y sombras. Pregúntate si realmente los necesitas.
- Cuando tengas dudas, siempre elige la opción que ofrezca un mejor rendimiento. Es posible que los usuarios no recuerden cuál es el ancho del padding de tus columnas, pero recordarán cómo se siente visitar tu sitio.
Conclusiones
Una de las cosas más interesantes de este experimento es que los tiempos seguirán cambiando con cada versión de Chrome (con suerte, serán más rápidos ;), ya que el software del navegador es una superficie en constante cambio. Lo que es lento hoy podría ser rápido mañana. Podrías evitar poner box-shadow: 1px 2px 3px 4px
en un elemento que ya tiene border-radius:5
. Sin embargo, la conclusión más valiosa debería ser que las propiedades CSS afectan directamente los tiempos de pintura de la página.