Loading https://github.com in the live GUI shows the macOS spinning wheel for ~30s+. Root-caused on 2026-06-10 (branch feat/js-stack-trampoline) with a UI-thread CPU trace during the stall: the navigation itself completes (first paint at ~4.8s), but show_page(+firstPresent) took 31s and the deferred-phase re-show another 23s. After load, the live loop keeps the process at ~200% CPU.
The trace shows the UI thread spending 20.9s of a 26.3s sample inside SixLabors GaussianBlur, reached via:
WebviewPanel.PresentSurface
-> Compositor.RenderToSurface -> EmitGpuTextureTile
-> ImageSharpBackend.RenderTexture -> ApplyFilterGroup -> ApplyFilterChain
-> GaussianBlur
GitHub's homepage CSS has large blurs on hero glow elements: blur(180px) x2, blur(150px), blur(100px) x2, blur(40-60px) several (site-*.css, home-*.css). The cost is new with the Tier-5 filters/backdrop work — before it, filter: was ignored.
Three multipliers stack:
ImageSharpBackend.ApplyFilterGroup (src/Starling.Paint/Backend/ImageSharpBackend.cs:2803) rasterizes the whole padded filter-group bounds into an offscreen Image<Rgba32> (up to 64M px) and blurs it on the CPU. Sigma scales with device scale, so retina doubles the kernel and quadruples the pixels.
Compositor.EmitGpuTextureTile (src/Starling.Paint/Compositor/Compositor.cs:422) hands every tile miss the layer's full display list, so the complete group blur re-runs once per 2048x512 tile the blurred layer touches.
- It all runs synchronously inside
ShowPage -> PresentSurface on the UI thread.
Work items
Evidence
- UI-thread dotnet-trace during the stall: 20.9s GaussianBlur inclusive, thread-pool workers pegged ~20s each in ImageSharp parallel convolution;
OnScrollChanged 14.8s inclusive (scroll re-blurs).
- Aspire structured logs:
first-paint: 4800 ms, show_page ... showPage(+firstPresent)=30999ms, second pass =23038ms.
- Memory note:
github-blur-present-stall (Claude Code project memory).
Loading https://github.com in the live GUI shows the macOS spinning wheel for ~30s+. Root-caused on 2026-06-10 (branch
feat/js-stack-trampoline) with a UI-thread CPU trace during the stall: the navigation itself completes (first paint at ~4.8s), butshow_page(+firstPresent)took 31s and the deferred-phase re-show another 23s. After load, the live loop keeps the process at ~200% CPU.The trace shows the UI thread spending 20.9s of a 26.3s sample inside SixLabors
GaussianBlur, reached via:GitHub's homepage CSS has large blurs on hero glow elements:
blur(180px)x2,blur(150px),blur(100px)x2,blur(40-60px)several (site-*.css,home-*.css). The cost is new with the Tier-5 filters/backdrop work — before it,filter:was ignored.Three multipliers stack:
ImageSharpBackend.ApplyFilterGroup(src/Starling.Paint/Backend/ImageSharpBackend.cs:2803) rasterizes the whole padded filter-group bounds into an offscreenImage<Rgba32>(up to 64M px) and blurs it on the CPU. Sigma scales with device scale, so retina doubles the kernel and quadruples the pixels.Compositor.EmitGpuTextureTile(src/Starling.Paint/Compositor/Compositor.cs:422) hands every tile miss the layer's full display list, so the complete group blur re-runs once per 2048x512 tile the blurred layer touches.ShowPage->PresentSurfaceon the UI thread.Work items
TypeError: Class extends value is not a constructoracross bundles (custom-elements path),JS stack overflowinelement-registry-*.js,Index was outside the bounds of the arrayinmarketing-essentials-*.js.EbrCollector::EnterCriticalRegionassert during exit finalizers (-[NSApplication terminate:]->__cxa_finalize_ranges-> managed VSD resolve). .NET 11 preview shutdown path; needs a repro/workaround (e.g. clean managed teardown beforeexit).Evidence
OnScrollChanged14.8s inclusive (scroll re-blurs).first-paint: 4800 ms,show_page ... showPage(+firstPresent)=30999ms, second pass=23038ms.github-blur-present-stall(Claude Code project memory).