¿Por qué algunas animaciones son lentas?

Los navegadores modernos pueden animar dos propiedades CSS de forma económica: transform y opacity. Si animas cualquier otra cosa, 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 y velocidad de fotogramas de la animación

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.
  4. Compuesto: Separa los elementos en capas y dibuja las capas en la pantalla.

Estos cuatro pasos se conocen como la 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 desde el paso que se debe cambiar para permitir que se realice 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 compilació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 más larga de todas las tareas de la canalización.

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

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 esté 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 debe volver a pintar esos elementos y no todo lo demás. Es posible que conozcas el concepto de capa de Photoshop, que contiene muchos 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 información sobre esto en Cómo crear animaciones de alto rendimiento. Sin embargo, la creación de capas nuevas debe hacerse con cuidado, ya que cada una usa memoria. En dispositivos con memoria limitada, crear capas nuevas puede causar más problemas de rendimiento que el que intentas resolver. Además, las texturas de cada capa deben subirse a la GPU. Por lo tanto, es posible que encuentres restricciones de ancho de banda entre la CPU y la GPU.

Rendimiento de CSS en comparación con JavaScript

Te preguntarás: ¿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) suelen controlarse en un subproceso conocido como subproceso de compositor. Esto es diferente del subproceso principal del navegador, en el que se ejecutan el diseño, el estilo, la pintura y JavaScript. Esto significa que, si el navegador ejecuta algunas tareas costosas en el subproceso principal, estas animaciones pueden continuar sin interrupciones.

Como se explica en este artículo, en muchos casos, el subproceso del compositor también puede controlar otros cambios en las transformaciones y la opacidad.

Si alguna animación activa la pintura, el diseño o ambos, el subproceso principal deberá realizar el trabajo. Esto es cierto para las animaciones de CSS y JavaScript, y es probable que la sobrecarga del diseño o la pintura eclipse cualquier trabajo asociado con la ejecución de CSS o JavaScript, lo que hace que la pregunta sea irrelevante.