perf(login): static shell gradient — fix general dashboard login jank#217
Merged
Merged
Conversation
The app.fivucsas dashboard login felt laggy across EVERY login screen (identifier / password / MFA / face), while verify.fivucsas stayed smooth — even with browser hardware-acceleration off on both. Root cause was the dashboard auth shell's decorative motion, not the face pipeline and not WebGPU (both surfaces share the same WASM/MediaPipe path): - `gradientShift`: the brand gradient was painted at `background-size: 400% 400%` with `background-position` animated infinitely. Animating background-position cannot be GPU-composited; it forces a full-viewport repaint every frame, on the main thread when hardware-acceleration is off. This ran on all login screens — the dominant cost. - 5x `FloatingShape` orbs each ran an infinite framer-motion animation with a per-frame `backdrop-filter: blur(10px)` re-composite. - the glass card `backdrop-filter: blur(20px)` re-blurred the moving gradient every frame. verify.fivucsas (HostedLoginApp) uses a STATIC radial gradient with no continuous animation — which is exactly why it is smooth. Fix (matches verify; same colours/layout; reversible): - shell gradient is now STATIC for everyone (no `gradientShift` pan) via the shared `loginShellBackgroundSx()`. - `FloatingShape` orbs become a ONE-SHOT fade/scale-in with a soft radial fill (no infinite repeat, no animated backdrop-blur) — decoration with zero per-frame cost after mount. - glass card blur kept on the (now static) off-camera screens; dropped during the live FACE/PUZZLE camera step and under prefers-reduced-motion. - honour prefers-reduced-motion (no orbs, flat card) as an extra layer. After this the dashboard login has no continuous compositing, so it renders as smoothly as verify.fivucsas. tsc + eslint + 380 auth tests + vite build green.
ahmetabdullahgultekin
added a commit
that referenced
this pull request
Jun 12, 2026
…ges (#218) The 7 standalone auth shells (Register, SecondaryAuthFlow, VerifyEmail, ResetPassword, Onboarding, AcceptInvite, ForgotPassword) each carried a byte-identical copy of the login-page jank anti-pattern that PR #217 already removed from LoginPage: - an infinite `gradientShift` keyframe animation over `backgroundSize: 400% 400%`, which animates `background-position` and so forces a full-viewport REPAINT every frame (main-thread when HW-accel is off); and - decorative `FloatingShape` orbs that ran an INFINITE framer-motion loop with a per-frame `backdrop-filter: blur(10px)`. Fix (presentational/perf only, behaviour-preserving): - Replace every inline animated-gradient `sx` block with the shared `loginShellBackgroundSx()` (static brand gradient, same stops) from loginBackground.ts. The `@keyframes gradientShift` are deleted. - Extract ONE shared decorative-orb component, `features/auth/components/FloatingShape.tsx` — the cheap ONE-SHOT fade/scale-in with a soft radial fill and no animated backdrop-blur (the target version LoginPage already shipped). LoginPage and all 7 pages now import it and their local inline `FloatingShape` definitions are removed (8 duplicate copies -> 1). - Gate the orbs behind `!usePrefersReducedMotion()` on every page that renders them, matching LoginPage. Each page keeps its exact colours, layout, glass-card `blur(20px)`, and orb positions/sizes/delays. Orb counts are preserved (5 on most; VerifyEmail keeps its 4; SecondaryAuthFlow renders none and only had an unused FloatingShape def + the animated gradient, both removed). Net -196 LOC across the 8 files plus the one shared component. Verified: tsc --noEmit clean, eslint clean on all changed files, vitest src/features/auth + src/pages 395/395 green, vite build OK.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
app.fivucsas dashboard login felt laggy on every screen (identifier / password / MFA / face), while verify.fivucsas stayed smooth — even with browser hardware-acceleration off on both. So it was not the face pipeline and not WebGPU (both surfaces share the same WASM/MediaPipe path).
Root cause (code-confirmed by comparing the two shells)
The dashboard auth shell ran continuous decorative motion that composited on the main thread:
gradientShift— brand gradient atbackground-size: 400% 400%withbackground-positionanimated infinitely → animating background-position can't be GPU-composited → full-viewport repaint every frame, on every login screen (the dominant cost).FloatingShapeorbs, each an infinite framer-motion animation with a per-framebackdrop-filter: blur(10px)re-composite.backdrop-filter: blur(20px)re-blurring the moving gradient each frame.verify-app/HostedLoginApp.tsxuses a static radial gradient with no continuous animation — exactly why it is smooth.Fix (matches verify; same colours/layout; fully reversible)
gradientShiftpan) via sharedloginShellBackgroundSx().FloatingShape→ one-shot fade/scale-in + soft radial fill (no infinite repeat, no animated backdrop-blur) → decoration with zero per-frame cost after mount.prefers-reduced-motion.prefers-reduced-motion(no orbs, flat card) as an extra a11y layer.Net: dashboard login has no continuous compositing → renders as smoothly as verify.
Verification
tsc --noEmit✅ ·eslint(changed files) ✅ · 380/380 auth vitest ✅ ·vite build✅Notes
The same
gradientShift+FloatingShapeanti-pattern is duplicated inline in 7 other auth pages (register / verify-email / reset / onboarding / accept-invite / forgot-password / secondary-auth). This PR fixes the login hot path; a DRY consolidation of the others is captured as a Phase-3 cleanup follow-up.