Skip to content

Respect prefers-reduced-motion in upload illustration#69

Merged
jasonmadigan merged 3 commits into
mainfrom
68-reduce-gpu-usage-landing-animation
Jun 5, 2026
Merged

Respect prefers-reduced-motion in upload illustration#69
jasonmadigan merged 3 commits into
mainfrom
68-reduce-gpu-usage-landing-animation

Conversation

@jasonmadigan

Copy link
Copy Markdown
Collaborator

Summary

  • Add useReducedMotion hook that tracks the OS-level prefers-reduced-motion setting via matchMedia
  • Gate all indefinite SMIL animations (<animate>, <animateTransform>) in UploadIllustration behind the hook -- when reduced motion is preferred, animations are removed from the DOM entirely rather than hidden, eliminating GPU compositing cost
  • Static SVG elements (paper, tools, phone, brackets) remain visible
  • Guard against missing matchMedia (older browsers/test envs) and avoid hydration mismatch by deferring the read to useEffect

Closes #68

Test plan

  • Existing 20 tests pass (pnpm test)
  • Enable "Reduce motion" in OS accessibility settings -- landing page illustration should render without animation
  • Disable "Reduce motion" -- animations should resume
  • Toggle setting while page is open -- should update live without reload
  • Check browser without matchMedia support (or mock it away) -- should default to animations enabled

The UploadIllustration SVG had 10+ concurrent SMIL animations
(scan line, corner pulses, phone bob, lens glow, dash offset)
running indefinitely, causing 40% GPU on older machines.

All animations are now gated behind a useReducedMotion hook that
listens to prefers-reduced-motion. When reduced motion is preferred,
static SVG renders with no SMIL elements. Entrance animations
(one-shot fade-in per tool) are also skipped for consistency.

Signed-off-by: Jason Madigan <[email protected]>
Moves 10/12 SVG SMIL animations to CSS @Keyframes using
compositor-only properties (transform, opacity). Pulse ring
r attribute replaced with scale(). stroke-dashoffset stays
as CSS animation. prefers-reduced-motion media query added
as CSS-level fallback alongside existing JS gating.

Signed-off-by: Jason Madigan <[email protected]>
@jasonmadigan
jasonmadigan marked this pull request as ready for review June 5, 2026 21:45
@jasonmadigan
jasonmadigan merged commit 35cf19a into main Jun 5, 2026
1 check passed
@jasonmadigan
jasonmadigan deleted the 68-reduce-gpu-usage-landing-animation branch June 5, 2026 21:46
shanetinklenberg pushed a commit to shanetinklenberg/tracefinity that referenced this pull request Jun 28, 2026
* Respect prefers-reduced-motion in upload illustration (tracefinity#68)

The UploadIllustration SVG had 10+ concurrent SMIL animations
(scan line, corner pulses, phone bob, lens glow, dash offset)
running indefinitely, causing 40% GPU on older machines.

All animations are now gated behind a useReducedMotion hook that
listens to prefers-reduced-motion. When reduced motion is preferred,
static SVG renders with no SMIL elements. Entrance animations
(one-shot fade-in per tool) are also skipped for consistency.

Signed-off-by: Jason Madigan <[email protected]>

* fix useReducedMotion hydration mismatch and matchMedia guard

Signed-off-by: Jason Madigan <[email protected]>

* Replace SMIL animations with CSS in UploadIllustration

Moves 10/12 SVG SMIL animations to CSS @Keyframes using
compositor-only properties (transform, opacity). Pulse ring
r attribute replaced with scale(). stroke-dashoffset stays
as CSS animation. prefers-reduced-motion media query added
as CSS-level fallback alongside existing JS gating.

Signed-off-by: Jason Madigan <[email protected]>

---------

Signed-off-by: Jason Madigan <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Image on title page causes high GPU usage on lower spec machines

1 participant