Why your scroll animations lag on mobile
Most janky scroll animations come from the same few mistakes. Here is what to check before you blame GSAP.
31 Oct 20261 min readPerformance, GSAP
A scroll animation that feels smooth on a laptop can stutter on a mid-range phone. It is rarely the library's fault. It is usually one of a handful of habits.
Animate transform and opacity only
The browser can move and fade a layer on the GPU without redoing layout. Anything else (top, left, width, height, margin) forces it to recalculate the page on every frame.
// Layout on every frame
gsap.to(card, { top: 200 })
// Composited, cheap
gsap.to(card, { y: 200 })Stop reading layout inside the loop
Calling getBoundingClientRect() or offsetWidth inside an onUpdate makes the browser flush layout every frame. Measure once, before the animation, and reuse the number.
const width = el.offsetWidth // once
ScrollTrigger.create({
onUpdate: ({ progress }) => {
gsap.set(bar, { x: progress * width })
},
})Be careful with filter and big blurs
filter: blur() and large box-shadow animations are expensive on phones. If you need a blur, blur a small element, or fade between a sharp and a pre-blurred copy.
Don't pin everything
Pinned sections are great for a moment of focus, but every pin adds work on resize and refresh, and long pins make the page feel endless on a phone. Pin one thing, keep it short.
Respect reduced motion
Some people get dizzy from motion. Check the preference and give them the end state:
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
gsap.set(el, { opacity: 1, y: 0 })
return
}Test on a real phone
Chrome's device mode emulates the screen size, not the CPU. Plug in a real phone, or at least throttle the CPU in DevTools, before you call it done.
Need this on your site?
I build interfaces like this for agencies, startups and SaaS teams.
Let's talk