CSS frente a JavaScript • Josh W. Comeau

CSS frente a JavaScript • Josh W. Comeau

Introducción

Una de las preguntas más comunes sobre el rendimiento de la animación es si las animaciones basadas en JS son más lentas que las basadas en CSS. ¿Deberíamos esforzarnos siempre por utilizar transiciones CSS o está bien utilizar bibliotecas de animación JavaScript?

Hay una sorprendente cantidad de matices en esta pregunta y creo que la sabiduría convencional no es del todo correcta. En esta publicación, profundizaremos en esta pregunta y veremos las diferencias por nosotros mismos.

Enlace a este encabezadoComparación de fotogramas clave CSS con bucles de JavaScript

Supongamos que estamos construyendo la siguiente animación:

Podemos conectar esto con un fotograma clave CSS, como este:

@keyframes bounce {
  to {
    transform: translateX(calc(var(--bounce-magnitude) * -1));
  }
}

.ball {
  --bounce-magnitude: 200px;
  animation: bounce 1000ms infinite alternate;
}

(Estoy usando una transformación CSS para esta animación porque produce el movimiento más suave. En los casos en que el tamaño del contenedor sea dinámico, necesitaríamos calcular y aplicar --bounce-magnitude en JS.)

Alternativamente, ¡podríamos implementar esta animación usando JavaScript! Antes de considerar bibliotecas JS como GSAP o Motion, comencemos con una versión JS simple:

const startTime = performance.now();

const ball = document.querySelector('.ball');

function animate() {
  const elapsedTime = performance.now() - startTime;

  // ✂️ Calculate `x` based on the amount of time that has passed.

  ball.style.transform = `translateX(${x}px)`;

  window.requestAnimationFrame(animate);
}

Este código utiliza requestAnimationFrame para ejecutar el animate función en cada fotograma (60 veces por segundo en la mayoría de las pantallas). He eliminado la lógica principal para calcular. x ya que es un poco complicado y no es relevante para el tema que nos ocupa, pero puedes verlo completo código(se abre en una nueva pestaña) si tienes curiosidad.

Aquí está la pregunta: ¿Qué enfoque crees que funciona mejor?

Creo que para la mayoría de nosotros, nuestras intuiciones nos dirían que la versión CSS tiene más rendimiento. Y nuestra intuición es correcta, pero tal vez no por las razones que pensamos. 😅

Se podría pensar que la versión JS es más lenta porque tiene que hacer todo ese trabajo extra calculando el x valor en cada cuadro, o que hay un costo adicional por “cruzar el puente” entre JavaScript y el DOM. Pero los motores de navegador modernos pueden abordar todas esas cosas sin sudar; Incluso en dispositivos de gama baja, ese trabajo ocurre en una pequeña fracción de milisegundo, demasiado rápido para afectar la velocidad de fotogramas de nuestra animación.

Pero hay una diferencia significativa: la versión de JavaScript se ejecuta en el hilo principal, junto con todo lo demás sucediendo en nuestra aplicación. Las transiciones CSS y las animaciones de fotogramas clave se ejecutan en un hilo separado, por lo que no se ven interrumpidas cuando suceden cosas en JavaScript.

Me he tomado la libertad de crear una simulación. Haga clic en el botón “Reproducir” para ejecutar la demostración. Cada pocos segundos, se bloqueará el hilo principal. Observe el efecto que tiene en estas dos animaciones:

En las aplicaciones web modernas, el hilo principal no mucho de trabajo. Los marcos de JavaScript como React actualizan constantemente el DOM para mantenerlo sincronizado con el estado de la aplicación. Cada vez que hacemos un fetch solicitud (por ejemplo, para cargar más datos o actualizar datos existentes), esa respuesta debe ser analizada por el hilo principal.

Entonces, si alguna vez has visto una ruleta congelarse por un momento antes de que se actualice la interfaz de usuario, ¡este es el motivo! Las animaciones basadas en JavaScript tienen que competir por la potencia de procesamiento con el resto de la aplicación.

En el ejemplo anterior, utilicé un requestAnimationFrame bucle para actualizar la interfaz de usuario en cada fotograma en JavaScript. Esta es una técnica de bastante bajo nivel; En la práctica, muchos desarrolladores utilizan bibliotecas de JavaScript que proporcionan una abstracción de nivel superior.

Comparemos dos bibliotecas de animación populares, Movimiento(se abre en una nueva pestaña) (anteriormente Framer Motion) y GSAP(se abre en una nueva pestaña):

¡Eh! Tanto Motion como GSAP están basados ​​en JavaScript, por lo que es de esperar que compartan las mismas limitaciones de ejecución en el hilo principal. Pero de alguna manera, Motion logra mantener la animación funcionando sin problemas incluso cuando el hilo principal está ocupado. 🤔

El secreto es que Motion utiliza las animaciones web. API(se abre en una nueva pestaña) (WAAPI) debajo del capó. WAAPI es esencialmente una interfaz JavaScript que se conecta al mismo motor de animación de bajo nivel que las animaciones de fotogramas clave CSS. Por lo tanto, Motion puede ejecutar sus animaciones en un hilo separado, evitando el principal problema de la mayoría de las otras bibliotecas de animación de JavaScript. 😮

Para ser justos con GSAP, es una biblioteca enormemente poderosa que incluye características que probablemente no sean compatibles con WAAPI. Entonces, no es que GSAP haya tomado la decisión equivocada, sino que están eligiendo diferentes compensaciones.

En mi propio trabajo, intento utilizar animaciones/transiciones CSS nativas siempre que puedo. Cuando me encuentro con situaciones que CSS por sí solo no puede manejar, intento usar una biblioteca como Motion, que resuelve el problema sin los inconvenientes típicamente asociados con las bibliotecas JS.

Dicho esto, CSS se ha vuelto tan poderoso que realmente no existen eso Hay muchos casos en los que hoy en día necesitamos recurrir a una biblioteca de animaciones; Las nuevas API como View Transitions, linear() y Animation Timeline permiten hacer todo tipo de cosas sin JavaScript. ✨

Exploramos todas estas herramientas, y mucho más, en mi nuevo curso, Whimsical Animaciones(se abre en una nueva pestaña). Le mostraré cómo diseño e implemento animaciones de primer nivel utilizando CSS, JavaScript, SVG y Canvas modernos.

Animaciones caprichosas, un curso de Josh W. Comeau

Hoy en día, los LLM son excelentes para generar sintaxis, pero aún debemos usar nuestro propio criterio. En esta publicación de blog, aprendimos sobre las consideraciones de rendimiento entre CSS y JavaScript, y mi curso está lleno de cosas como esta. Entonces, independientemente de si estás escribiendo código a mano o no, este curso te ayudará a crear animaciones e interacciones sorprendentes.

Puedes conocer más al respecto aquí:

Última actualización el

3 de junio de 2026

Source link

Posts Similares

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *