Cómo crear animaciones CSS de alto rendimiento

En esta guía, aprenderás a crear animaciones de CSS de alto rendimiento.

Consulta ¿Por qué algunas animaciones son lentas? para conocer la teoría detrás de estas recomendaciones.

Compatibilidad del navegador

Todas las propiedades de CSS que se recomienda en esta guía ofrecen una buena compatibilidad con varios navegadores.

transform

Navegadores compatibles

  • Chrome: 36.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

Origen

opacity

Navegadores compatibles

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 2.

Origen

will-change

Navegadores compatibles

  • Chrome: 36.
  • Edge: 79.
  • Firefox: 36.
  • Safari: 9.1.

Origen

Cómo mover un elemento

Para mover un elemento, usa los valores de las palabras clave translate o rotation de la propiedad transform.

Por ejemplo, para deslizar un elemento a la vista, usa translate.

.animate {
  animation: slide-in 0.7s both;
}

@keyframes slide-in {
  0% {
    transform: translateY(-1000px);
  }
  100% {
    transform: translateY(0);
  }
}

Usa rotate para rotar elementos. En el siguiente ejemplo, se rota un elemento 360 grados.

.animate {
  animation: rotate 0.7s ease-in-out both;
}

@keyframes rotate {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

Cómo cambiar el tamaño de un elemento

Para cambiar el tamaño de un elemento, usa el valor de palabra clave scale de la propiedad transform.

.animate {
  animation: scale 1.5s both;
}

@keyframes scale {
  50% {
    transform: scale(0.5);
  }
  100% {
    transform: scale(1);
  }
}

Cómo cambiar la visibilidad de un elemento

Para ocultar o mostrar un elemento, usa opacity.

.animate {
  animation: opacity 2.5s both;
}

@keyframes opacity {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

Evita las propiedades que activen el diseño o la pintura

Antes de usar cualquier propiedad CSS para la animación (excepto transform y opacity), determina el impacto de la propiedad en la canalización de renderización. Evita cualquier propiedad que active el diseño o la pintura, a menos que sea absolutamente necesario.

Cómo forzar la creación de capas

Como se explica en ¿Por qué algunas animaciones son lentas?, colocar elementos en una capa nueva permite que el navegador los vuelva a pintar sin tener que volver a pintar el resto del diseño.

Por lo general, los navegadores pueden tomar buenas decisiones sobre qué elementos deben colocarse en una capa nueva, pero puedes forzar la creación de capas de forma manual con la propiedad will-change. Como su nombre lo sugiere, esta propiedad le indica al navegador que este elemento se cambiará de alguna manera.

En CSS, puedes aplicar will-change a cualquier selector:

body > .sidebar {
  will-change: transform;
}

Sin embargo, la especificación sugiere que solo debes hacerlo para los elementos que siempre están a punto de cambiar. Por ejemplo, esto podría ser cierto para una barra lateral que el usuario puede deslizar hacia adentro y hacia afuera. Para los elementos que no cambian con frecuencia, te recomendamos que apliques will-change con JavaScript cuando sea probable que se produzca un cambio. Asegúrate de darle al navegador suficiente tiempo para realizar las optimizaciones necesarias y quita la propiedad cuando se detenga el cambio.

Si quieres forzar la creación de capas en un navegador que no admite will-change (lo más probable es que sea Internet Explorer), puedes establecer transform: translateZ(0).

Cómo depurar animaciones lentas o con errores

Chrome DevTools y Firefox DevTools tienen muchas herramientas para ayudarte a descubrir por qué tus animaciones son lentas o tienen errores.

Cómo verificar si una animación activa el diseño

Es probable que una animación que mueva un elemento con algo que no sea transform sea lenta. En el siguiente ejemplo, se compara una animación con transform con una animación con top y left.

Qué no debes hacer
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease infinite;
}

@keyframes move {
  50% {
     top: calc(90vh - 160px);
     left: calc(90vw - 200px);
  }
}
Qué debes hacer
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease infinite;
}

@keyframes move {
  50% {
     transform: translate(calc(90vw - 200px), calc(90vh - 160px));
  }
}

Puedes probar esto en los siguientes dos ejemplos de Glitch y explorar el rendimiento con DevTools.

Herramientas para desarrolladores de Chrome

  1. Abre el panel Rendimiento.
  2. Registra el rendimiento del tiempo de ejecución mientras se ejecuta la animación.
  3. Inspecciona la pestaña Resumen.

Si ves un valor distinto de cero para Renderización en la pestaña Resumen, podría significar que tu animación está haciendo que el navegador haga el trabajo de diseño.

El panel Resumen muestra 37 ms para la renderización y 79 ms para la pintura.
El ejemplo de animation-with-top-left genera trabajo de renderización.
En el panel Resumen, se muestran valores cero para el procesamiento y la pintura.
El ejemplo de animation-with-transform no causa trabajo de renderización.

Herramientas para desarrolladores de Firefox

En las Herramientas para desarrolladores de Firefox, Waterfall puede ayudarte a comprender en qué parte el navegador pasa el tiempo.

  1. Abre el panel Rendimiento.
  2. Comienza a registrar el rendimiento mientras se reproduce la animación.
  3. Detén la grabación y, luego, inspecciona la pestaña Cascada.

Si ves entradas para Recalculate Style, significa que el navegador debe volver al principio de la cascada de renderización para renderizar la animación.

Verifica si hay fotogramas descartados

  1. Abre la pestaña Renderización en las Herramientas para desarrolladores de Chrome.
  2. Habilita la casilla de verificación FPS meter.
  3. Observa los valores mientras se ejecuta la animación.

Presta atención a la etiqueta Frames en la parte superior de la IU del medidor de FPS. Esto muestra valores como 50% 1 (938 m) dropped of 1878. Una animación de alto rendimiento tiene un porcentaje alto, como 99%, lo que significa que se descartan pocos fotogramas y la animación se ve fluida.

El medidor de FPS muestra que se perdió el 50% de los fotogramas
El ejemplo animation-with-top-left hace que se descarte el 50% de los fotogramas.
El medidor de FPS muestra que solo se perdió el 1% de los fotogramas.
El ejemplo animation-with-transform hace que solo se descarte el 1% de los fotogramas.

Cómo comprobar si una animación activa la función de pintura

Algunas propiedades son más costosas para que el navegador las pinte que otras. Por ejemplo, todo elemento que incluya un desenfoque (como una sombra, por ejemplo) tardará más en pintarse que, por ejemplo, un cuadro rojo en dibujarse. Estas diferencias no siempre son evidentes en el CSS, pero DevTools del navegador puede ayudarte a identificar qué áreas deben volver a pintarse, así como otros problemas de rendimiento relacionados con la pintura.

Herramientas para desarrolladores de Chrome

  1. Abre la pestaña Renderización en las Herramientas para desarrolladores de Chrome.
  2. Selecciona Paint Flashing.
  3. Mueve el puntero por la pantalla.
Un elemento de la IU destacado en verde para demostrar que se volverá a pintar
En este ejemplo de Google Maps, puedes ver los elementos que se vuelven a pintar.

Si ves que toda la pantalla parpadea o que se destacan áreas que no crees que deberían cambiar, investiga un poco más.

Si necesitas determinar si una propiedad en particular causa problemas de rendimiento relacionados con la pintura, el generador de perfiles de pintura en las Herramientas para desarrolladores de Chrome puede ayudarte.

Herramientas para desarrolladores de Firefox

  1. Abre Configuración y agrega un botón de Toolbox para Toggle paint flashing.
  2. En la página que deseas inspeccionar, activa el botón y mueve el mouse o desplázate para ver las áreas destacadas.

Conclusión

Cuando sea posible, restringe las animaciones a opacity y transform para mantener las animaciones en la etapa de composición de la ruta de acceso de renderización. Usa DevTools para verificar qué etapa de la ruta se ve afectada por tus animaciones.

Usa el generador de perfiles de pintura para ver si alguna operación de pintura es particularmente costosa. Si encuentras algo, verifica si una propiedad CSS diferente brinda la misma apariencia con un mejor rendimiento.

Usa la propiedad will-change con moderación y solo si encuentras un problema de rendimiento.