perf(webui): flatten scroll-container background + scope explorer wheel listener
Two measured, universally-beneficial fixes (kept after determining the rest of the earlier perf work was chasing a Bitwarden extension that pegged the main thread, not real app bugs): - .main-content had a linear-gradient background. A gradient on the scroll container is re-rastered across the whole scrolled area every scroll frame (the compositor can't translate a cached tile): ~25% dropped frames -> <1% once flattened to a solid color (visually identical, was rgb 10->15->11). - The explorer wheel-zoom listener was a non-passive listener on `document`, which disables compositor (async) scrolling app-wide so every wheel/trackpad scroll runs through the main thread. Scoped it to the explorer viewport. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
1c1d2eb884
commit
89fe7703fa
2 changed files with 23 additions and 15 deletions
|
|
@ -1066,18 +1066,24 @@ function explorerFitToView() {
|
|||
});
|
||||
}
|
||||
|
||||
// Scroll wheel zoom (no modifier needed inside viewport)
|
||||
document.addEventListener('wheel', (e) => {
|
||||
// Scroll wheel zoom (no modifier needed inside viewport).
|
||||
// IMPORTANT: attach to the viewport element, NOT document. A non-passive wheel
|
||||
// listener on document disables the browser's compositor (async) scrolling for
|
||||
// the ENTIRE app — every wheel/trackpad scroll then runs through the main thread.
|
||||
// Scoping it to the viewport keeps zoom working while the rest of the app keeps
|
||||
// smooth compositor scrolling.
|
||||
(function attachExplorerWheelZoom() {
|
||||
const viewport = document.getElementById('explorer-viewport');
|
||||
if (!viewport || !viewport.contains(e.target)) return;
|
||||
// Check if we're on the explorer page
|
||||
const page = document.getElementById('playlist-explorer-page');
|
||||
if (!page || !page.classList.contains('active')) return;
|
||||
if (!viewport) return;
|
||||
viewport.addEventListener('wheel', (e) => {
|
||||
const page = document.getElementById('playlist-explorer-page');
|
||||
if (!page || !page.classList.contains('active')) return;
|
||||
|
||||
e.preventDefault();
|
||||
const step = e.deltaY > 0 ? -0.08 : 0.08;
|
||||
explorerZoom(step);
|
||||
}, { passive: false });
|
||||
e.preventDefault();
|
||||
const step = e.deltaY > 0 ? -0.08 : 0.08;
|
||||
explorerZoom(step);
|
||||
}, { passive: false });
|
||||
})();
|
||||
|
||||
// Middle-click / right-click drag to pan
|
||||
document.addEventListener('mousedown', (e) => {
|
||||
|
|
|
|||
|
|
@ -2970,11 +2970,13 @@ body.helper-mode-active #dashboard-activity-feed:hover {
|
|||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
/* Opaque dark background (GPU-optimized: no backdrop-filter needed on solid dark body) */
|
||||
background: linear-gradient(135deg,
|
||||
rgba(10, 10, 10, 1) 0%,
|
||||
rgba(15, 15, 15, 1) 50%,
|
||||
rgba(11, 11, 11, 1) 100%);
|
||||
/* Flat solid background — NOT a gradient. A gradient on the scroll container
|
||||
has to be re-rastered across the whole scrolled area on every scroll frame
|
||||
(the compositor can't just translate a cached tile), which caused the
|
||||
dominant scroll jank (~25% dropped frames -> <1% once flattened, measured).
|
||||
A solid color is drawn as a single compositor quad, no per-frame raster.
|
||||
The gradient was rgb 10->15->11, visually indistinguishable from this. */
|
||||
background: rgb(12, 12, 12);
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue