Cómo crear animaciones CSS de alto rendimiento

En esta guía, aprenderás a crear animaciones 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 recomienda esta guía tienen una buena compatibilidad entre navegadores.

transform

Browser Support

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

Source

opacity

Browser Support

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

Source

will-change

Browser Support

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

Source

Cómo mover un elemento

Para mover un elemento, usa los valores de 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 mostrar u ocultar 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 activan el diseño o la pintura

Antes de usar cualquier propiedad de CSS para la animación (que no sean 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.

Forzar la creación de la capa

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

Por lo general, los navegadores pueden tomar buenas decisiones sobre qué elementos se deben colocar en una capa nueva, pero puedes forzar manualmente la creación de capas con la propiedad will-change. Como su nombre lo indica, 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 agregar esto a los elementos que siempre están a punto de cambiar. Por ejemplo, esto se podría usar para una barra lateral que el usuario puede deslizar hacia adentro y hacia afuera. Si el elemento no cambia con frecuencia, aplica will-change con JavaScript cuando sea probable que se produzca un cambio. Asegúrate de darle al navegador el tiempo suficiente para realizar las optimizaciones necesarias y quita la propiedad cuando se detenga el cambio.

Para forzar la creación de capas en un navegador que no admite will-change, puedes establecer transform: translateZ(0).

Cómo depurar animaciones lentas o con fallas

Las Herramientas para desarrolladores de Chrome y las Herramientas para desarrolladores de Firefox pueden ayudarte a descubrir por qué tus animaciones son lentas o tienen fallas.

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

Es probable que una animación que mueve un elemento con algo que no sea transform sea lenta. En el siguiente ejemplo, se compara una animación que usa transform con una animación que usa 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 y explorar el rendimiento con las Herramientas para desarrolladores.

Herramientas para desarrolladores de Chrome

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

Si ves un valor distinto de cero para Renderización en la pestaña Resumen, es posible que tu animación esté haciendo que el navegador realice trabajo de diseño.

El panel Summary muestra 37 ms para la renderización y 79 ms para la pintura.
El ejemplo animation-with-top-left causa trabajo de renderización.
El panel Summary muestra valores cero para la renderización y la pintura.
El ejemplo animation-with-transform no causa trabajo de renderización.

Herramientas para desarrolladores de Firefox

En las Herramientas para desarrolladores de Firefox, la cascada puede ayudarte a comprender en qué está ocupado el navegador.

  1. Abre el panel Rendimiento.
  2. Comienza a grabar el rendimiento mientras se reproduce la animación.
  3. Detén la grabación y revisa la pestaña Waterfall.

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

Cómo verificar si hay pérdida de fotogramas

  1. Abre la pestaña Rendering 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 descartó el 50% de los fotogramas.
El ejemplo de animation-with-top-left hace que se descarten el 50% de los fotogramas
El medidor de FPS muestra que solo se descartó el 1% de los fotogramas.
El ejemplo de animación con transformación hace que se descarte solo el 1% de los fotogramas.

Cómo verificar si una animación activa la pintura

Algunas propiedades son más costosas para el navegador que otras. Por ejemplo, todo lo que implica un desenfoque (como una sombra) tarda más en pintarse que dibujar una caja roja. Estas diferencias no siempre son evidentes en el CSS, pero las Herramientas para desarrolladores del navegador pueden ayudarte a identificar qué áreas deben volver a pintarse, así como otros problemas de rendimiento relacionados con el pintado.

Herramientas para desarrolladores de Chrome

  1. Abre la pestaña Rendering en las Herramientas para desarrolladores de Chrome.
  2. Selecciona Pintar parpadeo.
  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 cómo se repintan los elementos.

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

Si necesitas determinar si una propiedad en particular está causando problemas de rendimiento relacionados con la pintura, el perfilador 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.

Anima en la etapa de composición

Cuando sea posible, restringe las animaciones a opacity y transform para mantenerlas en la etapa de composición de la ruta de procesamiento. Usa las Herramientas para desarrolladores 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 otra propiedad de CSS ofrece el mismo aspecto y la misma experiencia con un mejor rendimiento.

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