Do Scroll Animations Hurt Performance?
Analyze the performance impact of scroll animations: scroll event listeners vs IntersectionObserver vs CSS Scroll-Driven Animations API, and INP impact.
Core Takeaway
Traditional scroll animations that use window.addEventListener('scroll') severely damage performance by running JavaScript synchronously on every scroll tick and blocking user input. In contrast, modern declarative approaches like CSS Scroll-Driven Animations and IntersectionObserver run completely off the main thread or batch work asynchronously, delivering smooth 60 FPS without degrading Interaction to Next Paint (INP).
The scroll listener bottleneck
Attaching a scroll event listener that queries element.getBoundingClientRect() or pageYOffset forces synchronous layout recalculation (layout thrashing) on every frame. When a user scrolls rapidly on a touch screen, the main thread locks up, causing stutter and failing Google's Core Web Vitals metric (INP).
IntersectionObserver for trigger-based reveals
For elements that animate into view when scrolled into the viewport, IntersectionObserver is the gold standard. It calculates intersection boundaries asynchronously in the browser compositor without firing synchronous callbacks on every scroll pixel.
- Never query getBoundingClientRect() inside a raw scroll listener
- Use IntersectionObserver with rootMargin for viewport entry reveals
- Adopt CSS Scroll-Driven Animations (@scroll-timeline) for off-thread progress
- Ensure passive: true is set on any residual scroll event listeners
CSS Scroll-Driven Animations (@scroll-timeline)
Modern browsers support CSS scroll() and view() timeline functions. This allows animations to link directly to scroll progress on the compositor thread without a single line of JavaScript executing during the scroll interaction.
Accessibility and vestibular safety
Large parallax backgrounds and continuous scroll-linked scaling can induce dizziness and nausea in users with vestibular disorders. Always disable scroll-linked parallax under prefers-reduced-motion.
Key Principles to Remember
- Never bind synchronous layout reads to raw window scroll events
- Use IntersectionObserver to trigger entry animations cleanly
- Embrace native CSS Scroll-Driven Animations for off-main-thread progress
- Strip parallax effects entirely when prefers-reduced-motion is detected
Frequently Asked Questions
Sources
- Scroll-driven animations specification — W3C
- Optimize Interaction to Next Paint (INP) — Google Web.dev