Accessibility & performance

For some users, your animation is a medical event. Respect that.

Two non-negotiable requirements: respect motion preferences and keep 60fps.

prefers-reduced-motion

A more targeted approach:

Reduced motion users don't want zero feedback. They want animation that doesn't move across the screen.

In JavaScript

Or use Motion's useReducedMotion hook:

Transform and opacity only

transform and opacity run entirely in the composite stage. Everything else triggers layout or paint.

Animate transform and opacity. Nothing else.

PropertyTriggersPerformance
transform (translate, scale, rotate)CompositeSmooth
opacityCompositeSmooth
filter (blur, brightness)PaintTest on mobile
box-shadowPaintCan stutter with large spreads
background-colorPaintAvoid during drag
width, height, top, leftLayout + PaintNever animate
border-radiusPaintNever animate
clip-path (inset, circle)CompositeSmooth with will-change

will-change: use sparingly

will-change: transform on 200 list items creates 200 compositor layers.

  1. Apply before animation starts (on mouseenter, modal about to open).
  2. Remove after animation completes (on transitionend).
  3. Never apply in a static stylesheet to elements that "might" animate.

Off-screen pausing

For CSS animations, toggle animation-play-state: paused when not intersecting.

Layout animation gotchas

Motion's layout prop on fifty elements means fifty position recalculations per frame.

The performance test

Test on a two-year-old Android phone. Enable paint flashing in DevTools. Below 50fps? Simplify.