ae99757dddfa2640b1b343e93f9de7e0c96edcf0
Collapsing the sidebar dropped frames only on the artist page. The cause was one observer: the app grid animates its columns for 280ms, a ResizeObserver fires on every frame of that, and this canvas answered each one with a full resize() -- 171-224ms of main thread per toggle, 10-12 frames over 16ms, worst frame 54ms. Muting that single observer took the worst frame to 4.3ms; muting every other observer changed nothing. Two independent per-frame stalls inside it. Reallocating the ~3200x1630 backing store was 115-205ms of the total, and the box moved about a pixel per frame, so every one of those reallocations bought an invisible sharpness change. gl.getError() after every draw is a synchronous round trip to the GPU process, and it stalls hardest exactly when the GPU is busy compositing the animation that provoked it. reflow() is the observer's path now: it repaints into the CURRENT store and matches the store to the box once, 140ms after the box settles. What makes that correct is taking the cover crop from the DISPLAYED box while outSize normalizes by the store -- the two may then disagree, because a crop chosen for a 1.80 box drawn into a 1.96 store is stretched by exactly the ratio the compositor undoes painting store into box. Geometrically exact at every intermediate width, no reallocation. The error check is skipped on that path only; the settle pass that follows is checked, so a real failure still surfaces. After: 1.5-2.4ms per toggle across 46 calls, max 0.2ms each. No frame over 33ms, 0-2 over 16ms. The Now Playing collapse rides the same transition and improved with it. resize is no longer exposed: every caller outside this file is reacting to a box that may still be moving, and that is reflow's job.
Languages
Rust
48.3%
Svelte
38.1%
JavaScript
13.4%
CSS
0.2%