GSAP Animations in Production
How I use GSAP on client sites without hurting performance — scroll triggers, page transitions, and knowing when to stop.
Animation is the fastest way to make a site feel premium — or the fastest way to make it feel slow. On projects like MBBank, Inno JSC, and OKHub, I use GSAP to add motion that supports the brand, not distracts from it.
My default stack
- GSAP for timeline-based animations
- ScrollTrigger for scroll-linked effects
- Swiper for carousels with parallax slides
prefers-reduced-motionchecks where motion isn't essential
A simple hero entrance
useEffect(() => {
const ctx = gsap.context(() => {
gsap.from(".hero-title", {
y: 40,
opacity: 0,
duration: 0.8,
ease: "power3.out",
})
})
return () => ctx.revert()
}, [])Always wrap GSAP in gsap.context() and clean up on unmount. Orphaned tweens cause jank when navigating in Next.js.
Rules I follow
- Animate transform and opacity — avoid layout-triggering properties
- One hero moment per page — not every element needs to fly in
- Respect reduced motion — offer a static fallback
- Test on mid-range phones — if it stutters on a 3-year-old Android, dial it back
- Lazy-init ScrollTrigger — don't register triggers for off-screen sections immediately
Parallax without the lag
On project galleries I use Swiper's parallax module with watchSlidesProgress instead of heavy scroll listeners on every frame. Less main-thread work, smoother swipes.
When not to use GSAP
For simple hover states or toggles, CSS transitions are enough. GSAP earns its place when you need sequenced timelines, scroll choreography, or cross-element coordination.
Motion should feel intentional — like the site is responding to you, not performing for you.