perf: suspend parked New Tab and Settings renderers
Home creates unused WebKit warmups even when those pages use Chromium, and starts warm New Tab and Settings pages whose parking views have zero opacity. Warmup now checks the selected engine before allocating WebKit pages, using the latest claim options for both build and recycling. The spares now hide after their first paint (and the New Tab cover snapshot) and wake synchronously when adopted. Pending snapshot callbacks check ownership and generation before hiding anything.
Leo's request: "when it comes to the left scroll rail thing, i already said we want it ultra fast ultra responsive, but the same goes for EVERYTHING IN THE WEB UI" and "how could rendering be this fucking slow? ... There's just loads of bullshit in my sidebar that I'm not even looking at ... This is an M5 Pro ... get shit done."
No new timers or animation loops. A parked view owns a capture lifecycle callback: it wakes for a replacement cover after a late chat-list answer, then sleeps after that capture; adoption and drop clear it, and weak ownership checks reject stale calls. Paint/snapshot callbacks run once; a claim, reparent, replacement capture, dropped spare or pool release prevents a stale callback from hiding an active page. Existing transport pacing holds nonurgent pushes while hidden. Risk: a warm page's first reveal or cover image could regress, so native opening latency and captures were measured before landing.
Validation
python3 scripts/cmux-next/prepush-gate.pypassed; app-size warnings only.- App compile passed at
6b1b108043c(cmux-ci compile-check --app, job6b53ddf99dca). - Real-GUI native lifecycle tests passed at the final head with no skips: PageHostPool visibility 3/3 and
NewTabSpareVisibilityTests.aParkedSpareWakesForItsReplacementCoverAndSleepsAgain(step65824ea1a4f1). The old-code pool check fails its intended assertions at:27and:42(step5c93507911af); the old-pool New Tab check fails the hidden-replacement assertion at:78(stepf02ee807f509). - Independent Astra review passed at exact head
6b1b108043c. - Every A/B arm used the same fleet Mac with a GUI session, exclusive measure class, fresh scratch HOME, and the default engine on both sides. Idle arms compare
c83f3215 + perf-10x-idle.shagainst that same baseline plus the3a7653b0..6b1b1080patch; feat-cmux-next had no published cmux-tui tree afterc83f3215.
Performance
| metric | before | after | delta | harness or run link |
|---|---|---|---|---|
| Idle footprint at launch | 1804.8 MB | 1033.2 MB | −771.6 MB (−43%) | Native A/B, same fleet Mac, perf-10x-idle.sh |
| Idle footprint, second window | 1170.0 MB | 1036.7 MB | −133.3 MB (−11%) | same A/B |
| CEF renderer footprint at launch | 857.7 MB | 363.3 MB | −494.4 MB | same A/B; two hot renderers −488 MB |
| WebKit WebContent footprint | 119 MB / 3 processes | 45 MB / 2 processes | −74 MB / 1 process | same A/B |
| New Tab visible p50 | 10.8 ms | 14.8 ms | +4.0 ms (+37%) | n=24, debug.new_tab matched A/B |
| New Tab visible p90 | 21.2 ms | 20.5 ms | −0.7 ms (−3%) | same A/B; one frame in every run; p=0.17 |
| Settings claim-to-ready p50 | 48.0 ms | 57.0 ms | +9.0 ms (+19%) | n=8, CMUX_PAGE_CLAIM_BENCH=8 matched A/B |
| Settings claim-to-ready p90 | 65.7 ms | 61.6 ms | −4.1 ms (−6%) | same A/B; claim acknowledgement +3.6 ms |
The Settings p50 increase is a flagged tradeoff: a small claim-path increase was observed; whether suspension causes it remains unsettled, while p90 improves and the much larger renderer and memory reduction applies at idle. The sample is eight claims, so this is recorded for follow-up rather than treated as a settled regression. New Tab visible p50 did not show a significant regression (p=0.17), p90 improved, and every run painted in one frame.
Changelog
Changed: Unused WebKit warmups are skipped; warm New Tab and Settings pages stop drawing while parked out of sight.
Before / after
Real-app first-frame and 1-second captures compare 3a7653b0 with 6b1b1080 in light and dark: New Tab at launch, New Tab after 60 seconds idle, and Settings after 60 seconds idle. No blank, stale, or wrong cover was observed. New Tab used its parked spare (spare:true) at 37.7 ms after launch and 41.4 ms after idle; these individual observations are separate from the A/B distribution above.
After: tour-new-tab
Capture tour-new-tab at 6b1b108043c9 (fleet build, capture mini, text checked for private data)
| Light | Dark |
|---|---|
![]() | ![]() |
After: scene-settings
Capture scene-settings at 6b1b108043c9 (fleet build, capture mini, text checked for private data)
| Light | Dark |
|---|---|
![]() | ![]() |
Before: tour-new-tab
Capture tour-new-tab at 3a7653b054ed (fleet build, capture mini, text checked for private data)
| Light | Dark |
|---|---|
![]() | ![]() |
Before: scene-settings
Capture scene-settings at 3a7653b054ed (fleet build, capture mini, text checked for private data)
| Light | Dark |
|---|---|
![]() | ![]() |
Agent session: agent session







