Patrones de rendimiento GSAP aplicados en la landing de Roast Analytics — transforms, quickTo, stagger eficiente y ScrollTrigger sin layout thrashing.
Cada regla de la skill puesta en práctica con código real del proyecto Roast Analytics.
x, y, scale, rotation y opacity. Nunca left, top, width o height — se mantiene en el compositor.gsap.quickTo() en x/y, reutilizando un único tween por propiedad en lugar de crear miles en cada mousemove.gsap.to(cards, { stagger: 0.08 }) en lugar de 6 tweens independientes con delay manual.will-change: transform, opacity en CSS. No se aplica a todos los divs "por si acaso".ScrollTrigger.refresh() se llama una vez al terminar la carga, con debounce en resize. No en cada evento de scroll.Ejemplos reales del refactor aplicado a la landing de Roast Analytics.
// ❌ Causa layout thrashing en cada frame gsap.to(".card", { left: "200px", top: "50px", width: "300px", duration: 0.6, ease: "power2.out" }); // Resultado: layout recalculation en // cada tick → jank en gama media
// ✅ Solo compositor — 0 layout cost gsap.to(".card", { x: 200, y: 50, scaleX: 1.15, duration: 0.6, ease: "power2.out" }); // Resultado: translateX/translateY en GPU // → 60fps estables en todos los devices
// ❌ Crea cientos de tweens por segundo document.addEventListener("mousemove", (e) => { gsap.to("#cursor", { x: e.pageX, y: e.pageY, duration: 0.3 }); }); // ~60 tweens/seg → memory pressure // → frames saltados en scroll simultáneo
// ✅ Un solo tween, actualizado por quickTo const xTo = gsap.quickTo("#cursor", "x", { duration: 0.4, ease: "power3" }); const yTo = gsap.quickTo("#cursor", "y", { duration: 0.4, ease: "power3" }); document.addEventListener("mousemove", (e) => { xTo(e.pageX); yTo(e.pageY); });
// ❌ 6 tweens independientes, mayor overhead const cards = document.querySelectorAll(".feat-card"); cards.forEach((card, i) => { gsap.from(card, { opacity: 0, y: 28, delay: i * 0.08, // manual! duration: 0.55 }); }); // Resultado: 6 tweens con delay calculado // a mano — gestión duplicada
// ✅ Un solo tween con stagger interno const cards = gsap.utils.toArray(".feat-card"); gsap.from(cards, { opacity: 0, y: 28, duration: 0.55, stagger: 0.08, // GSAP lo gestiona ease: "power2.out" }); // GSAP reutiliza internamente el tween // y calcula el timing automáticamente
Medidos con Chrome DevTools Performance en MacBook Air M1 y Moto G6 (low-end).
Referencia rápida extraída directamente de la skill gsap-rendimiento-animaciones.
transform (x, y, scale, rotation) y opacity; se procesan en el compositor GPU.will-change: transform en CSS únicamente en los elementos que van a animar.gsap.quickTo() para propiedades actualizadas con alta frecuencia (cursor, scroll parallax).stagger en lugar de muchos tweens independientes con delay manual.ScrollTrigger.refresh() solo cuando el layout cambia de verdad; debounced en resize.left, top, width, height, margin o padding para movimiento — disparan layout en cada frame.will-change o force3D: true en todos los elementos "por precaución".gsap.to() dentro de mousemove sin usar quickTo.ScrollTrigger.refresh() en cada evento de scroll o resize sin debounce.