vruz.dev
Notas
Performance7 min

Motion avanzado con GSAP y ScrollTrigger en Next.js sin destrozar el INP

Cómo implementar parallax multicapa y scroll pineado de alto impacto visual manteniendo 60 FPS estables y cero penalización en Core Web Vitals.

  • #gsap
  • #scrolltrigger
  • #motion
  • #performance
  • #next.js
  • #itsjaruba

Al construir la plataforma para creadores como ItsJaruba (itsjaruba.com), el requerimiento visual es radicalmente distinto al de una web corporativa tradicional: el usuario espera una experiencia inmersiva con animaciones cinematográficas, parallax por capas y paneles pineados que reaccionan al milímetro al scroll. Sin embargo, añadir librerías pesadas de animación suele destruir la métrica INP (Interaction to Next Paint) y provocar tirones (jank) si no se programa con extremo rigor.

El ciclo de vida en React 19 y Next.js App Router

El principal dolor de cabeza al usar GSAP en entornos de renderizado moderno es la hidratación y los renders repetidos. Para evitar crear ScrollTriggers duplicados o dejar listeners huérfanos en memoria al navegar entre rutas, utilizo el hook de contexto de GSAP (gsap.context) encapsulando todos los selectores dentro de una referencia de contenedor:

``typescript useLayoutEffect(() => { const ctx = gsap.context(() => { gsap.to('.hero-layer-bg', { yPercent: 30, ease: 'none', scrollTrigger: { trigger: containerRef.current, start: 'top top', end: 'bottom top', scrub: true, }, }); }, containerRef); return () => ctx.revert(); }, []); ``

El método ctx.revert() en la función de limpieza del efecto garantiza que cada timeline, tween y observador de scroll se destruya limpiamente cuando el componente se desmonta.

Animar solo en la GPU: transforms y opacity

Para sostener 60 FPS fijos incluso en dispositivos móviles, nunca se deben animar propiedades que disparen el cálculo de geometría del navegador (Layout/Reflow) como top, left, margin o height. En su lugar, animo exclusivamente transform (xPercent, yPercent, scale, rotate) y opacity.

Aplicar la propiedad CSS will-change: transform a los elementos que tienen parallax continuo le indica al motor del navegador que reserve una capa de composición en la GPU de antemano, eliminando micro-congelaciones en el inicio del scroll.

Pineo suave y scrubbing sincronizado

Al pinear secciones (pinning) para desglosar media kits o características interactivas, configuro anticipatePin: 1 para que ScrollTrigger anticipe el momento exacto en que la sección alcanza el tope de la ventana gráfica, evitando saltos visuales de 1 pixel que suelen ocurrir en pantallas con tasas de refresco dinámicas (ProMotion a 120Hz).

Respeto a prefers-reduced-motion

Un motion premium es también un motion accesible. Utilizo window.matchMedia('(prefers-reduced-motion: reduce)') para desactivar de forma condicional las traslaciones espaciales complejas si el usuario tiene activada la reducción de movimiento en su sistema operativo, renderizando el contenido estático con transiciones simples de opacidad sin alterar el flujo ni la legibilidad.

¿Construyendo algo?

Si esto te ha resonado, podemos hablar. Contactar →