¿Por qué algunas animaciones son lentas?

Los navegadores modernos pueden animar dos propiedades de CSS de forma económica: transform y opacity. Si animas cualquier otra cosa, es probable que no alcances los 60 fotogramas por segundo (FPS) fluidos. 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 contenido 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 (1,000 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. Style: 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. Composite: 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 deben repetirse. Este proceso comienza desde el paso que se debe cambiar para permitir que se lleve a cabo 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 ejecutar de nuevo. 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 debas volver a calcular la geometría de otros elementos. Por ejemplo, si cambias el ancho del elemento <html>, cualquiera de sus elementos secundarios puede verse afectado. 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 tardará en realizar los cálculos de diseño.

Cómo animar propiedades de pintura

Pintar es el proceso de determinar en qué orden se deben pintar los elementos en la pantalla. A menudo, es la tarea que más tiempo tarda en ejecutarse de todas las tareas de la canalización.

La mayoría de las operaciones de pintura en los navegadores modernos se realizan en rasterizadores de software. Según cómo se agrupen los elementos de tu app en capas, es posible que también deban pintarse 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 eso, la propiedad opacity se incluye en la lista de elementos que son económicos de animar. Siempre y cuando esta propiedad esté en su propia capa, la GPU puede controlar los cambios durante el paso de composición. Los navegadores basados en Chromium y WebKit crean una nueva capa para cualquier elemento que tenga una transición o animación CSS en opacity.

¿Qué es una capa?

Si colocas los elementos que se animarán o a los que se les aplicará una transición en una capa nueva, el navegador solo tendrá que volver a pintar esos elementos y no todo lo demás. Es posible que conozcas el concepto de capa de Photoshop, que contiene varios 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 al tomar decisiones sobre qué elementos deben estar en una capa nueva, si omite uno, hay formas de forzar la creación de capas. Puedes obtener más información en Cómo crear animaciones de alto rendimiento. Sin embargo, la creación de capas nuevas debe hacerse con cuidado, ya que cada capa usa memoria. En los 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 alcances las restricciones de ancho de banda entre la CPU y la GPU.

Rendimiento de CSS en comparación con JavaScript

Quizás te preguntes si, desde la perspectiva del rendimiento, es mejor usar CSS o JavaScript para las animaciones.

Las animaciones basadas en CSS y Web Animations (en los navegadores que admiten la API) se suelen controlar en un subproceso conocido como subproceso del compositor. Esto es diferente del hilo principal del navegador, en el que se ejecutan el diseño, la pintura, el diseño y JavaScript. Esto significa que, si el navegador está ejecutando algunas tareas costosas en el subproceso principal, estas animaciones pueden seguir ejecutándose sin interrupciones.

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

Si alguna animación activa la pintura, el diseño o ambos, el subproceso principal deberá realizar trabajo. Esto se aplica tanto a las animaciones de CSS como a las de JavaScript, y la sobrecarga de diseño o pintura probablemente eclipsará cualquier trabajo asociado con la ejecución de CSS o JavaScript, lo que hará que la pregunta sea irrelevante.