Performance
Parallax still costs GPU and main-thread work, but this library no longer drives motion from a scroll handler that writes styles every frame. Visual progress is handled by scroll-driven Web Animations (ScrollTimeline / ViewTimeline + element.animate()), so the browser advances keyframes with scroll on the compositor.
How motion is appliedâ
- Scroll-linked WAAPI â Each parallax element gets a scroll-driven animation.
transform(translate, rotate, scale) andopacityare the animated properties, which map well to compositor-friendly updates. - No per-scroll style writes â Scrolling does not loop elements to set inline
transform/opacity. The animation timeline carries progress; JavaScript is not on the hot path for rendering each frame. - View timelines by default â Unless you set explicit
startScroll/endScroll, progress follows when the subject enters, crosses, and leaves the scrollport. Layout-derivedanimation-rangeadjustments align that progress with your configured effects. - Explicit scroll timelines â When you pass numeric
startScroll/endScroll, aScrollTimelineties progress to scroll offsets on the window or scroll container.
Animations are only installed when the browser exposes ScrollTimeline, ViewTimeline, and HTMLElement.prototype.animate. Unsupported environments skip scroll-driven setup (no silent fallback to manual scrolling).
What JavaScript still doesâ
Work is kept off the scroll path except when you opt into callbacks:
| When | Work |
|---|---|
Element add, resize, focus/blur, load, update() | Measure layout (getBoundingClientRect()), recompute keyframes and timeline options, (re)attach animations |
ResizeObserver on the scrollport | Same as above when the view or container size changes |
onEnter / onExit | IntersectionObserver only when those callbacks are set |
onProgressChange / onChange | One passive scroll listener on the window or scroll container, coalesced with a single requestAnimationFrame per frame â reads animation progress only; does not drive visuals |
Avoid onProgressChange / onChange on large numbers of elements unless you need them; they are the main reason scroll events touch your code.
Tips for smooth scrollingâ
- Prefer fewer, simpler effects â Many simultaneous scroll-driven animations still increase compositor and paint cost.
- Limit concurrent in-view effects â Elements visible together each hold an active animation.
- Optimize media â Large images and heavy DOM under animated nodes still hurt scroll feel.
- Respect
prefers-reduced-motionâ Disable or simplify parallax when users request reduced motion (your app or wrapper can setdisabledon the controller). - Test target browsers â Scroll-driven animations need current Chromium, Safari, and Firefox versions; verify on devices you ship to.
If you have ideas to further improve performance, please open a PR or issue.
Scroll effects can still hurt UXâ
You are responsible for using the library appropriately.
- Keep motion subtle â extreme translate/scale on many layers reads as janky even when technically smooth.
- Do not rely on progress callbacks for core UI; use them for analytics or secondary UI, not layout.
- Rebuild cost: calling
update()or resizing the scroll container rebuilds animations; avoid doing that continuously.