Skip to content

perf(sidebar): a folded session's step lays nothing out, only its roll-up state does - #31783

Merged
teamleaderleo merged 1 commit into
feat-cmux-nextfrom
lane/sidebar-offscreen-work
Nov 2, 2026
Merged

teamleaderleo merged 1 commit into
feat-cmux-nextfrom
lane/sidebar-offscreen-work

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Leo, 2026-10-28: "There's just loads of nonsense in my sidebar that I'm not even looking at. So how could rendering be this f***ing slow?"

Leo-ask: ask-268456b5a0

What was slow

With the session tree on, a session folded under its parent shows up only in the parent's roll-up (blocked / failed / running / unread counts). But SidebarListView.patchRows treated every patch to a hidden session as a height change. So each agent step, title or preview update (several a second per working agent) ran a full reload: it rebuilt the workspace/group/section maps and laid out every row. The more agents a person has folded away, the more often the sidebar re-lays out rows they can't see.

Fix

SidebarSessionTreeState.patchChangesRollUp(from:to:) asks for a layout only when the hidden session's counted state (SidebarAgentState.of, the same value the roll-up counts) changes. Other patches to a hidden session cost the dictionary write and nothing else. Rows that are on screen patch in place as before.

The PR adds no timers, observers or animation loops.

Test

SidebarSessionTreeTests.aFoldedSessionsStepLaysNothingOutButItsStateDoes: a step or title change on a folded session asks for no layout. A state change does, and so does a session the list hasn't seen before. A session that isn't hidden never does, because its own row patches. Under a lane state, the row's own activity is ignored.

Performance

metric before after delta harness
full list reloads per hidden-session patch that keeps its state 1 0 -1 code path (patchRowsNow → showModelChange → reload); unit test above

Risk: small, one component. A folded parent's chips now update only when a descendant's agent state changes. That matches what the chips count.

Agent session: agent session

🤖 Generated with Claude Code


Summary by cubic

Fixes the sidebar so a session folded under its parent no longer triggers a full re-layout on every step, title, or preview update. Those updates happen several times a second per working agent, so the more agents were folded away, the more often the sidebar re-laid out rows that weren't visible. Now only a change to the hidden session's counted state (the value the parent's roll-up chips display) causes a layout.

  • Added SidebarSessionTreeState.patchChangesRollUp(from:to:) to decide whether a patch changes a folded ancestor's roll-up; other patches cost only the dictionary write.
  • Rows on screen and sessions not hidden under a fold still patch their own row in place as before.

Written for commit c0f5a4e. Summary will update on new commits.

View guided diff Turn on auto-fix

…y its roll-up state does

A session hidden under a folded parent draws only as the parent's roll-up
(blocked, failed, running, unread counts), but every patch to it (each
agent step, title, preview) laid the whole list out again. Lay out only when
its counted state moves.

Leo-ask: ask-268456b5a0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-08e5d574de30b5b732c6
@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

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

Review c0f5a4e: 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=pr31783 -f ref=lane/sidebar-offscreen-work -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 a252e92; does not block

Shipped in:

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 2, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5 medium): SHIP at c0f5a4e
Follow-ups: none required. A folded parent's chips count only its sessions' agent state (unread, activity, agentWorking). A step, title or preview change can't move those counts. The previous value comes from the list's own workspace map, which reload fills from every node, hidden sessions included.

@blacksmith-sh

blacksmith-sh Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Found 12 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp34ls72za/summary-fail.json (live):/summary-fail.json (live): View Logs
/tmp/tmpqyx6oo1l/summary-missing.json (live):/summary-missing.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
main.DeveloperIdAppTests.test_download_prints_the_active_profile_only/
test_download_prints_the_active_profile_only
View Logs
stubs: /System/Library/Frameworks/Security.framework/Versions/A/Security has no stub/
Security has no stub
View Logs
stubs: CoreFoundation.tbd: install-name /System/Library/Frameworks/
CoreFoundation.framework/Versions/A/CoreFoundation, missing 1: ['_CFRetain']/
CoreFoundation, missing 1: ['_CFRetain']
View Logs
stubs: CoreFoundation.tbd: install-name /System/Library/Frameworks/
CoreFoundation.framework/Versions/A/CoreFoundation, missing 1: ['_log2']/
CoreFoundation, missing 1: ['_log2']
View Logs

...and 2 more test failures. View all on Blacksmith

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

@teamleaderleo
teamleaderleo merged commit 8b5e78e into feat-cmux-next Nov 2, 2026
151 of 164 checks passed
@teamleaderleo
teamleaderleo deleted the lane/sidebar-offscreen-work branch November 2, 2026 04:27
teamleaderleo added a commit that referenced this pull request Nov 2, 2026
Conflicts kept base's newer sidebar work beside lineage nesting:
- SidebarSessionTreeFeed: the pull request capture fixture (no GitHub reads) and the nesting-only pass.
- SidebarLayout+DoneFold: the Archived (N) fold and Archive-section drag unfold, folding whole runs.
- SidebarLayout+Fold: archived-group fast-path exits plus the lineage one.
- SidebarRowIndex: a folded session's step lays nothing out (#31783), with the per-list fold check.
- SidebarTreeRollUpView: the running spinner ring (#31455) beside the total chip.
- SidebarNestedFixture: soleMember and lineageGroup scenarios.
- SidebarListView+Layout: a drag unfolds Done, Archived and the Archive section, lineage-aware.
The Archive section no longer turns off with the session tree, which nesting now sets for everyone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639

This branch was previously deployed

1 inactive deployment
ci-routing-agent — c0f5a4ef Deployed Nov 2, 2026 by teamleaderleo via wait for same-key tree publisher #99155
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