Caso de éxito sobre el rendimiento de las animaciones basadas en desplazamientos

Yuriko Hirota
Yuriko Hirota

¿Qué novedades hay en las animaciones basadas en desplazamientos?

Las animaciones impulsadas por el desplazamiento son una forma de agregar interactividad y atractivo visual a tu sitio web o aplicación web, que se activan según la posición de desplazamiento del usuario. Esta puede ser una excelente manera de mantener la participación de los usuarios y hacer que tu sitio web sea más atractivo a nivel visual.

En el pasado, la única forma de crear animaciones impulsadas por el desplazamiento era responder al evento de desplazamiento en el subproceso principal. Esto causó dos problemas principales:

  • El desplazamiento se realiza en un subproceso independiente y, por lo tanto, entrega eventos de desplazamiento de forma asíncrona.
  • Las animaciones del subproceso principal están sujetas a bloqueos.

Esto hace que sea imposible o muy difícil crear animaciones de desplazamiento de alto rendimiento que estén sincronizadas con el desplazamiento.

Ahora presentamos un nuevo conjunto de APIs para admitir animaciones basadas en el desplazamiento, que puedes usar desde CSS o JavaScript. La API intenta usar la menor cantidad posible de recursos de subproceso principal, lo que facilita mucho la implementación de las animaciones impulsadas por el desplazamiento y también las hace mucho más fluidas. Actualmente, la API de animaciones impulsadas por el desplazamiento es compatible con los siguientes navegadores:

Navegadores compatibles

  • Chrome: 115.
  • Edge: 115.
  • Firefox: Detrás de una marca.
  • Safari: No se admite.

Origen

En este artículo, se compara el nuevo enfoque con la técnica clásica de JavaScript para mostrar lo fáciles y fluidas que pueden ser las animaciones impulsadas por el desplazamiento con la nueva API.

La API de CSS de animaciones basadas en el desplazamiento en comparación con el JavaScript clásico

La siguiente barra de progreso de ejemplo se compila con técnicas de clase de JavaScript.

El documento responde cada vez que se produce el evento scroll para calcular el porcentaje de scrollHeight hasta el que se desplazó el usuario.

document.addEventListener("scroll", () => {
  var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
  var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
  var scrolled = (winScroll / height) * 100; 
  document.getElementById("progress").style.width = scrolled + "%";
})

En la siguiente demostración, se muestra la misma barra de progreso con la nueva API y CSS.

@keyframes grow-progress {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

#progress {
  animation: grow-progress auto linear forwards;
  animation-timeline: scroll(block root);
}

La nueva función CSS animation-timeline convierte automáticamente una posición en un intervalo de desplazamiento en un porcentaje de progreso, por lo que realiza todo el trabajo pesado.

Ahora, esta es la parte interesante: supongamos que implementaste un cálculo muy pesado en ambas versiones del sitio web que consumiría la mayor parte de los recursos del subproceso principal.

function someHeavyJS(){
  let time = 0;
  window.setInterval(function () {
    time++;
    for (var i = 0; i < 1e9; i++) {
      result = i;
    }
    console.log(time)
  }, 100);
}

Como era de esperar, la versión clásica de JavaScript se vuelve inestable y lenta debido a la unión de recursos del subproceso principal. Por otro lado, la versión de CSS no se ve afectada en absoluto por el trabajo pesado de JavaScript y puede responder a las interacciones de desplazamiento del usuario.

El uso de la CPU es completamente diferente en DevTools, como se muestra en las siguientes capturas de pantalla.

Comparación del subproceso principal.

En la siguiente demostración, se muestra una aplicación de animación impulsada por desplazamiento creada por CyberAgent. Verás que la foto se desvanece a medida que te desplazas.

Nueva API de JavaScript de animaciones impulsadas por el desplazamiento en comparación con el JavaScript clásico

El beneficio de la nueva API no se limita solo al CSS. También puedes crear animaciones suaves y fluidas impulsadas por el desplazamiento con JavaScript. Observa el siguiente ejemplo:

const progressbar = document.querySelector('#progress');
progressbar.style.transformOrigin = '0% 50%';
progressbar.animate(
  {
    transform: ['scaleX(0)', 'scaleX(1)'],
  },
  {
    fill: 'forwards',
    timeline: new ScrollTimeline({
      source: document.documentElement,
    }),
  }
);

Esto te permite crear la misma animación de barra de progreso que se muestra en la demostración de CSS anterior con solo JavaScript. La tecnología subyacente es la misma que la versión de CSS. La API intenta usar la menor cantidad posible de recursos de subproceso principal, lo que hace que las animaciones sean mucho más fluidas en comparación con el enfoque clásico de JavaScript.

Además, esta nueva API funciona en conjunto con la API de Web Animations (WAAPI) y la API de CSS Animations existentes para habilitar animaciones declarativas impulsadas por el desplazamiento.

Más demostraciones y recursos

Puedes consultar las diferentes implementaciones de la animación impulsada por el desplazamiento a través de este sitio de demostración, en el que puedes comparar demostraciones con estas nuevas APIs de CSS y JavaScript.

Si te interesa obtener más información sobre las nuevas animaciones impulsadas por el desplazamiento, consulta este artículo y la conferencia de I/O 2023.