From 9454970a83214a1e1e2fd887349adb0ad7842178 Mon Sep 17 00:00:00 2001 From: BoulderBadgeDad Date: Mon, 22 Jun 2026 15:01:49 -0700 Subject: [PATCH] perf(dashboard): sidebar header sweep animates transform, not left MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .sidebar-header::after ambient sweep animated `left` (-100% -> 140%) on an 8s infinite loop — forcing a layout recalc every frame it's on screen, on the sidebar that's present on every page. Convert to transform: translateX() with a pixel-identical travel path (element is 60% of header width, so translateX(400%) == the old 240%-of-header sweep) + will-change. Compositor-only now; no per-frame layout. Zero visual change. --- webui/static/style.css | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/webui/static/style.css b/webui/static/style.css index 456d6a41..432bc341 100644 --- a/webui/static/style.css +++ b/webui/static/style.css @@ -340,14 +340,20 @@ body.reduce-effects .sidebar::after { rgba(var(--accent-rgb), 0.06) 60%, transparent 100% ); + /* Animate transform (compositor-only) instead of `left` (which forced a + layout recalc every frame). The element width is 60% of the header, so + translateX(400%) = 240% of header width — the same travel `left:-100%` + → `left:140%` produced. Pixel-identical path, no per-frame layout. */ + transform: translateX(0); + will-change: transform, opacity; animation: sidebar-header-sweep 8s ease-in-out infinite; pointer-events: none; } @keyframes sidebar-header-sweep { - 0%, 100% { left: -100%; opacity: 0; } + 0%, 100% { transform: translateX(0); opacity: 0; } 10% { opacity: 1; } - 50% { left: 140%; opacity: 1; } + 50% { transform: translateX(400%); opacity: 1; } 60% { opacity: 0; } }