Rendimiento de animación: la búsqueda de 60 FPS
Las animaciones locas destruyen la sensación de lujo. Comprender el proceso de renderizado del navegador (diseño, pintura, compuesto) para lograr un movimiento suave y mantecoso.
Un sitio web de lujo se siente “pesado” en importancia, pero “ligero” en rendimiento.
Cuando hago clic en un botón, el modal debería deslizarse instantáneamente, como seda sin esfuerzo.
Si tartamudea, se retrasa o pierde fotogramas, la ilusión se rompe.
60 fotogramas por segundo (FPS) es el estándar de oro.
Para lograr 60 FPS, el navegador tiene 16,6 milisegundos para renderizar un fotograma.
(1000 ms / 60 fotogramas = 16,66 ms).
Si tomas 17 ms, pierdes un fotograma. El usuario ve “Jank”.
Para solucionar este problema, debe comprender cómo piensa el navegador.
Por qué Maison Code habla de esto
En Maison Code Paris, actuamos como la conciencia arquitectónica de nuestros clientes. A menudo heredamos stacks “modernos” construidos sin una comprensión fundamental de la escala.
Discutimos este tema porque representa un punto de inflexión crítico en la madurez de la ingeniería. Implementarlo correctamente diferencia un MVP frágil de una plataforma resistente de nivel empresarial.
Por qué Maison Code obsesiona con más de 60 FPS
No vendemos productos; Vendemos sentimientos. Una animación entrecortada parece “barata”. Se siente como la manija de la puerta de un Ferrari rota. Aplicamos un estricto Presupuesto de rendimiento para las animaciones. Si una animación provoca un cambio de diseño, la eliminamos. Creemos que El movimiento es semántica. Explica la interfaz. Pero el movimiento sin rendimiento es sólo ruido.
1. El canal de renderizado del navegador
Cuando actualizas un estilo, el navegador pasa por 3 etapas:
- Diseño (Caro): Cálculo de geometría. “¿Qué ancho tiene este div? ¿Dónde se ubica?”
- Se activa cambiando:
ancho,alto,izquierda,arriba,margen.
- Se activa cambiando:
- Pintura (Mediana): Rellenar píxeles.
- Se activa al cambiar:
color de fondo,borde,sombra.
- Se activa al cambiar:
- Compuesto (Barato): organizar capas.
- Se activa cambiando:
transformar,opacidad.
- Se activa cambiando:
La regla de oro: animar solo propiedades compuestas.
- Malo:
transición: altura 0,3 s. (Disposición de activadores en cada cuadro = uso intensivo de CPU). - Bueno:
transición: transformación 0,3 s. (Solo disparadores compuestos = GPU acelerado).
2. Efecto de escala versus efecto de ancho
Quieres que un botón crezca cuando se coloca sobre él.
- Enfoque ingenuo:
Esto hace a un lado todos los elementos vecinos. El navegador debe volver a calcular la posición de todo el diseño de la página. Jank..btn:hover {ancho: 120px; } - Enfoque profesional:
Esto promueve el botón a una nueva capa. La GPU lo escala como una textura. Los elementos vecinos no se mueven. Liso. Consejo: Utilice.btn:hover { transformar: escala(1.1); }will-change: transformpara indicarle al navegador que promocione la capa con anticipación.
3. Técnica FLIP (El truco de magia)
A veces necesitas cambiar el diseño (por ejemplo, reordenar una lista o expandir una tarjeta). Utilice el principio FLIP (Primero, Último, Invertir, Reproducir).
- Primero: Medir la posición inicial
(x: 0). - Último: Mueve el elemento a la posición final (instantáneo). Mídelo
(x: 100). - Invertir: Utilice
transformpara moverlo atrás a la posición inicial visualmente(transform: TranslateX(-100px)). - Reproducir: anima la transformación a 0.
El usuario ve un movimiento suave, pero el navegador solo calculó el diseño una vez y luego animó la transformación.
Bibliotecas como Framer Motion manejan esto automáticamente con
<diseño de motion.div>.
4. Bibliotecas de animación JavaScript
CSS es más rápido para transiciones simples. Para física compleja (resortes), necesita JS.
- Framer Motion: el estándar de React. Excelente DX, pero el paquete es pesado (30 kb).
- GSAP: el estándar de la industria para desarrolladores creativos. Plazos sólidos. Licencia costosa para algunas funciones.
- React Spring: basado en la física. Bueno para una sensación “natural”.
Consejo de rendimiento: ejecute animaciones fuera del ciclo de renderizado de React. Si su animación actualiza React State en cada cuadro, eliminará el hilo principal. Utilice referencias y manipulación directa de DOM (o bibliotecas que hagan esto, como GSAP).
5. El cuello de botella móvil (modo de bajo consumo)
Tu MacBook Pro M3 Max puede animar cualquier cosa. El teléfono Android de 3 años de su usuario en “Modo de ahorro de batería” no puede hacerlo. La aceleración de la CPU es real. Prueba en dispositivos de gama baja. Si su efecto “Parallax Scroll” calienta el teléfono, desactívelo. Utilice la consulta de medios “prefiere movimiento reducido” para respetar la configuración del usuario. Un sitio accesible es un sitio eficaz.
6. Depuración de FPS (DevTools)
Abra Chrome DevTools -> pestaña Rendimiento. Graba la animación. Busque Triángulos rojos. “Tarea larga”. “Recalcular estilo”. Si ve mucha actividad de diseño (barras moradas), está animando las propiedades incorrectas. Active “Paint Flashing” en la pestaña Renderizado. Los destellos verdes muestran lo que se está repintando. Idealmente, nada debería parpadear durante una animación de transformación. Bordes de capa: active esta opción para ver qué elementos se promocionan a la GPU.
7. La trampa de React useLayoutEffect
En React, useEffect se ejecuta después de pintar.
Si mide elementos DOM en useEffect, el usuario ve un marco donde el elemento está en el lugar incorrecto y luego se ajusta.
Utilice useLayoutEffect para realizar mediciones.
Bloquea la pintura hasta realizar la medición.
Utilízalo con moderación, ya que pausa el hilo principal.
Pero para la inicialización de la animación (FLIP), es obligatorio evitar fallos visuales.
8. El modelo RAIL (La doctrina del rendimiento de Google)
Google define 4 momentos clave en el rendimiento: R.A.I.L.
- Respuesta: Procesar eventos en < 50 ms. Si hago clic, debo ver los comentarios al instante.
- Animación: produce un fotograma en < 16 ms (60 fps).
- Inactivo: Maximiza el tiempo de inactividad. Trabaje cuando el usuario no esté interactuando.
- Cargar: entregue contenido y vuélvalo interactivo en < 5 segundos. Si viola RAIL, Google castiga su clasificación SEO. No se trata sólo de “velocidad”. Se trata de “Percepción”. Un retraso de 100 ms le parece a un usuario 1 segundo.
9. Fuera del hilo principal: trabajadores web
JavaScript es de un solo subproceso. Si analiza un archivo JSON enorme, la interfaz de usuario se congela. Solución: Trabajadores web. Mueva lógica pesada (análisis de datos, compresión de imágenes, cifrado) a un trabajador.
trabajador constante = nuevo trabajador('trabajador.js');
trabajador.postMessage(hugeData);
El hilo principal permanece gratuito para la interfaz de usuario (desplazarse, hacer clic). Bibliotecas como Comlink lo hacen más fácil. En 2026, la “Arquitectura fuera del hilo principal” será la predeterminada.
10. Estudio de caso: el carrusel de 60 FPS
Construimos un carrusel de productos para un cliente de moda de lujo.
Restricción: 50 imágenes de alta resolución. Pergamino infinito. Transiciones 3D.
Error V1: Estado de reacción activeIndex. Se volvió a representar la lista completa en cada deslizamiento. 15 FPS.
V2 arreglado:
- Virtualización: Solo se renderizan las 3 diapositivas visibles.
- Corrección: Se usó
transform: TranslateX3d()para la aceleración de hardware. - Will-Change: Insinuó el navegador.
- Decodificación de imágenes: Se utiliza
decoding="async"en imágenes. Resultado: 60 FPS sólidos en un iPhone 8. La diferencia no fue el marco; fue la física del navegador.
11. WebGL y Canvas (Rompiendo el DOM)
Para animaciones extremas (miles de partículas, modelos 3D), el DOM es demasiado lento. Vaya a WebGL (a través de Three.js o React Three Fiber). WebGL dibuja directamente en el búfer de la GPU. Omite por completo el proceso de Diseño/Pintura. Así construimos experiencias de lujo estilo “Awwwards”. Pero tenga cuidado: la accesibilidad se vuelve mucho más difícil en WebGL. Canvas no admite lectores de pantalla de forma predeterminada.
12. El medidor de FPS (observabilidad)
No se puede arreglar lo que no se puede medir.
Chrome tiene un medidor de FPS, pero los usuarios no.
Inyectamos un pequeño FPS Listener en producción (para el 1% de los usuarios).
Utiliza el bucle requestAnimationFrame para medir el tiempo delta.
Si los fotogramas caen por debajo de 30 durante 5 segundos, registramos un evento en Sentry.
Rendimiento: FPS bajo detectado en /product/123.
Esto nos dice exactamente qué página es pesada en el mundo real (no sólo en nuestra MacBook Pro).
13. Los formatos de imagen (Avif vs WebP)
La animación no es sólo CSS; se esta cargando. Si su imagen de héroe tarda 3 segundos en cargarse, la animación de entrada tartamudea. WebP es el estándar. AVIF es el futuro (un 20% más pequeño que WebP). Pero los navegadores deben decodificarlos en el hilo principal (principalmente). Estrategia:
- Utilice la etiqueta
<imagen>como alternativa. - Utilice el atributo
decoding="async"en<img>. - BlurHash: muestra un pequeño desenfoque de 20 píxeles mientras se carga la imagen pesada. Esto reduce la “latencia percibida”.
14. Conclusión
El rendimiento no es una idea de último momento. Es una restricción de diseño. Si no puedes animarlo a 60 FPS, no lo animes en absoluto. Una interfaz estática es mejor que una retrasada. Respeta la batería del usuario. Respetar el tiempo del usuario. Hazlo volar.
¿Las caídas de cuadros matan la vibra?
Auditamos el rendimiento del Frontend y optimizamos animaciones para 60 FPS en dispositivos de gama baja.
Suavizar mi interfaz de usuario. Contrate a nuestros arquitectos.