¿Por qué algunas animaciones son lentas?

Los navegadores modernos pueden animar dos propiedades de CSS de forma económica: transform y opacity. Si animas algo más, es probable que no alcances los 60 fotogramas por segundo (FPS) de una manera fluida. En esta publicación, se explica por qué sucede esto.

Rendimiento de la animación y velocidad de fotogramas

Se acepta ampliamente que una velocidad de fotogramas de 60 FPS es el objetivo cuando se anima cualquier elemento en la Web. Esta velocidad de fotogramas garantizará que tus animaciones se vean fluidas. En la Web, un fotograma es el tiempo que se tarda en realizar todo el trabajo necesario para actualizar y volver a pintar la pantalla. Si cada fotograma no se completa en 16.7 ms (1000 ms / 60 ≈ 16.7), los usuarios percibirán la demora.

La canalización de renderización

Para mostrar algo en una página web, el navegador debe seguir los siguientes pasos secuenciales:

  1. Estilo: Calcula los estilos que se aplican a los elementos.
  2. Diseño: Genera la geometría y la posición de cada elemento.
  3. Pintar: Completa los píxeles de cada elemento en las capas.
  4. Compuesto: Dibuja las capas en la pantalla.

Estos cuatro pasos se conocen como canalización de renderización del navegador.

Cuando animas algo en una página que ya se cargó, estos pasos se deben volver a realizar. Este proceso comienza en el paso que se debe cambiar para permitir que se produzca la animación.

Como se mencionó antes, estos pasos son secuenciales. Por ejemplo, si animas algo que cambia el diseño, los pasos de pintura y composición también se deben volver a ejecutar. Por lo tanto, animar algo que cambia el diseño es más costoso que animar algo que solo cambia la composición.

Cómo animar propiedades de diseño

Los cambios de diseño implican calcular la geometría (posición y tamaño) de todos los elementos afectados por el cambio. Si cambias un elemento, es posible que se deba volver a calcular la geometría de otros elementos. Por ejemplo, si cambias el ancho del elemento <html>, es posible que se vea afectado cualquiera de sus elementos secundarios. Debido a la forma en que los elementos se desbordan y se afectan entre sí, los cambios más abajo en el árbol a veces pueden generar cálculos de diseño hasta la parte superior.

Cuanto más grande sea el árbol de elementos visibles, más tiempo tardará en realizar los cálculos de diseño.

Cómo animar propiedades de pintura

Paint es el proceso de determinar en qué orden se deben pintar los elementos en la pantalla. A menudo, es la tarea del proceso que más tiempo se ejecuta.

La mayor parte del proceso de pintura en los navegadores modernos se realiza en rasterizadores de software. Según cómo se agrupen los elementos de la app en capas, es posible que también se deban pintar otros elementos, además de los que cambiaron.

Cómo animar propiedades compuestas

La composición es el proceso de separar la página en capas, convertir la información sobre cómo debería verse la página en píxeles (rasterización) y unir las capas para crear una página (composición).

Por este motivo, la propiedad opacity se incluye en la lista de elementos que son económicos de animar. Siempre que esta propiedad se encuentre en su propia capa, la GPU puede controlar los cambios en ella durante el paso de composición. Los navegadores basados en Chromium y WebKit crean una capa nueva para cualquier elemento que tenga una transición o animación de CSS en opacity.

¿Qué es una capa?

Cuando se colocan los elementos que se animarán o pasarán a una nueva capa, el navegador solo necesita volver a pintar esos elementos y no todo lo demás. Es posible que estés familiarizado con el concepto de una capa de Photoshop, que contiene un montón de elementos que se pueden mover juntos. Las capas de renderización del navegador son similares a esa idea.

Si bien el navegador hace un buen trabajo a la hora de tomar decisiones sobre qué elementos deben estar en una capa nueva, si se pierde uno, hay formas de forzar la creación de la capa. Puedes obtener más información en Cómo crear animaciones de alto rendimiento. Sin embargo, la creación de nuevas capas se debe realizar con cuidado, ya que cada una de ellas utiliza memoria. En dispositivos con memoria limitada, crear capas nuevas puede causar un problema de rendimiento mayor que el que intentas resolver. Además, las texturas de cada capa deben subirse a la GPU. Por lo tanto, es posible que te encuentres con restricciones de ancho de banda entre la CPU y la GPU.

Rendimiento de CSS en comparación con JavaScript

Te preguntarás si es mejor usar CSS o JavaScript para las animaciones desde una perspectiva de rendimiento.

Las animaciones basadas en CSS y las animaciones web (en los navegadores que admiten la API) generalmente se manejan en un subproceso conocido como subproceso compositor. Esto es diferente del subproceso principal del navegador, donde se ejecutan el estilo, el diseño, la pintura y JavaScript. Esto significa que, si el navegador tiene en ejecución algunas tareas costosas en el subproceso principal, estas animaciones se pueden seguir ejecutando sin interrupciones.

Como se explica en este artículo, en muchos casos, el subproceso compositor también puede controlar otros cambios en las propiedades Transformaciones y Opacidad.

Si alguna animación activa elementos de pintura, diseño o de ambas clases, el subproceso principal deberá hacer el trabajo. Esto se aplica a las animaciones basadas en CSS y JavaScript, y es probable que la sobrecarga de diseño o pintura reduzca la cantidad de trabajo asociado con la ejecución de CSS o JavaScript, por lo cual el asunto sería irrelevante.