Skip to content

perf: suspend parked New Tab and Settings renderers - #26975

Merged
teamleaderleo merged 7 commits into
feat-cmux-nextfrom
lane/home-perf-renderers
Oct 29, 2026
Merged

teamleaderleo merged 7 commits into
feat-cmux-nextfrom
lane/home-perf-renderers

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

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.py passed; app-size warnings only.
  • App compile passed at 6b1b108043c (cmux-ci compile-check --app, job 6b53ddf99dca).
  • Real-GUI native lifecycle tests passed at the final head with no skips: PageHostPool visibility 3/3 and NewTabSpareVisibilityTests.aParkedSpareWakesForItsReplacementCoverAndSleepsAgain (step 65824ea1a4f1). The old-code pool check fails its intended assertions at :27 and :42 (step 5c93507911af); the old-pool New Tab check fails the hidden-replacement assertion at :78 (step f02ee807f509).
  • 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.sh against that same baseline plus the 3a7653b0..6b1b1080 patch; feat-cmux-next had no published cmux-tui tree after c83f3215.

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
light dark

After: scene-settings

Capture scene-settings at 6b1b108043c9 (fleet build, capture mini, text checked for private data)

Light Dark
light dark

Before: tour-new-tab

Capture tour-new-tab at 3a7653b054ed (fleet build, capture mini, text checked for private data)

Light Dark
light dark

Before: scene-settings

Capture scene-settings at 3a7653b054ed (fleet build, capture mini, text checked for private data)

Light Dark
light dark

Agent session: agent session

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-aiqxn8 created for this PR by the cmux coordinator.

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 28, 2026
teamleaderleo pushed a commit that referenced this pull request Oct 29, 2026
feat-cmux-next c83f321 (newest with a published cmux-tui tree) + perf-10x-idle.sh from the tip
f2e623b (#27110 setup fix) + #26975 diff 3a7653b..6b1b108. Deleted after the run.
@teamleaderleo
teamleaderleo marked this pull request as ready for review October 29, 2026 02:18
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 6b1b108: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr26975 -f ref=lane/home-perf-renderers -f platform=macos -f backend_mode=local

red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base 8b01895; does not block

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent, correctness first): SHIP at 6b1b108

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Real-app capture: parked pages wake cleanly (before 3a7653b0 vs after 6b1b1080)

DEV builds of both SHAs from the fleet. Each row is its own capture run: a fresh app on a fleet mini with a real display, a scratch home, default settings (Chromium agent chat). Stills are the app's own window snapshot, taken right after the open with no wait ("first frame"), or 1 s after it. Text in every still was checked for private data before upload.

Result: no blank, stale or wrong cover in the after build. Every New Tab still shows the composer and its controls, and every Settings still shows General with all its rows, the same as before. In the after build, debug.new_tab state at 1 s reports the opening came from the parked spare (spare: true) after launch (37.7 ms) and after 60 s idle (41.4 ms).

Light

moment before 3a7653b0 after 6b1b1080
1. New Tab right after launch: first frame before after
1. New Tab right after launch: 1 s later before after
2. New Tab after 60 s idle (parked spare wakes): first frame before after
2. New Tab after 60 s idle: 1 s later before after
3. Settings after 60 s idle: first frame before after
3. Settings after 60 s idle: 1 s later before after

Dark

moment before 3a7653b0 after 6b1b1080
1. New Tab right after launch: first frame before after
1. New Tab right after launch: 1 s later before after
2. New Tab after 60 s idle (parked spare wakes): first frame before after
2. New Tab after 60 s idle: 1 s later before after
3. Settings after 60 s idle: first frame before after
3. Settings after 60 s idle: 1 s later before after

Notes:

  • New Tab is opened through the New Tab Page action on the focused pane (the Cmd-T path, debug.new_tab open_and_type), 8 s after launch so the launch restore has landed. The CLI's cmux tab new-page adds the tab in the background without selecting it, so it can't show the page.
  • Settings is opened with settings.open after 60 s idle. Settings opens as a tab beside the Home chat.
  • Before and after ran on different fleet minis: the capture lease picks a free display mini, and both are the same macOS and window size. Layout differences between columns are host timing, not the PR.

🤖 Generated with Claude Code
Agent session: agent session

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Orphaned: no activity for 13 h, and no lane holds a lease on it. Adopted by the orphan sweep: merged feat-cmux-next in at 2a798a6. A later pass queues it for the merge hub if it is reviewed, small and red only on base reds.

@blacksmith-sh

blacksmith-sh Bot commented Oct 29, 2026

Copy link
Copy Markdown

Found 6 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmpffvsjlx7/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmpteo_d301/summary-fail.json (live):/summary-fail.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high, next-review): SHIP at 2a798a6

No blocking findings.

@cmux-bot cmux-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmux-bot approves 2a798a6: an independent review passed this exact head (next-review receipt by teamleaderleo). A push needs a new review; a later BLOCK at this head dismisses this approval.

@teamleaderleo
teamleaderleo merged commit 12b4dc0 into feat-cmux-next Oct 29, 2026
157 of 160 checks passed
@teamleaderleo
teamleaderleo deleted the lane/home-perf-renderers branch October 29, 2026 23:36
@github-actions

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/40974281406 at 12b4dc0 failed: cmux-next checks (god files, concurrency, crash safety, l10n).
Those jobs last passed at d918111. This pull request is one of 2 merged since: #26286, #26975.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

lawrencecchen added a commit that referenced this pull request Oct 30, 2026
… kept (review: trunk #26975 lost)

Trunk 12b4dc0 suspended the parked spare's renderer after its warm frame; the
merge deleted NewTabSparePool (perf's preload slot replaced it) and the slot hides
the page only with newTabParksHidden, which is off in every build. Ported onto
AgentPanePreloadPage: without parksHidden the page view hides once its remembered
frame was taken, wakes for a capture of the app's New Tab frame (a late chats.page
answer) and sleeps again after it; the claim shows it and drops the callback, so a
late capture cannot hide an adopted page. Trunk's capture seams (nextFrameOverride,
snapshotOverride, newTabFrameCaptureChanged) are used again.

Test: NewTabPreloadTests.theNewTabPageParksRenderingUnlessItParksHidden now asserts
the sleep, the wake for a New Tab frame capture, the sleep after it, and no hide
after the claim (red without this change: the page view never hides).

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 2a798a69 Deployed Oct 29, 2026 by teamleaderleo via wait for same-key tree publisher #77470
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant