Repository navigation
perf(sidebar): a folded session's step lays nothing out, only its roll-up state does - #31783
Conversation
…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
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base a252e92; does not block Shipped in:
|
|
Review (subagent claude-opus-5-5 medium): SHIP at c0f5a4e |
|
Found 12 test failures on Blacksmith runners: Failures
...and 2 more test failures. View all on Blacksmith
|
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
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
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.patchRowstreated 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 fullreload: 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
patchRowsNow→showModelChange→reload); unit test aboveRisk: 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.
SidebarSessionTreeState.patchChangesRollUp(from:to:)to decide whether a patch changes a folded ancestor's roll-up; other patches cost only the dictionary write.Written for commit c0f5a4e. Summary will update on new commits.