CmuxTabsKit: build only nearby grid cards; dormant hidden grid
AZ
9d ago+463+463+012345678901234567890123456789-34-34-01234567890123456789
Summary
CmuxTabsKit's tab grid builds only the cards near the screen and does no body work while it is hidden. These are the kit-only commits of the cmux-next iOS lists rebuild (manaflow-ai/cmux PR against feat-cmux-next from feat-cmux-next-ios-smooth-lists), proposed here so Packages/iOS/CmuxTabsKit stays identical on both branches.
- Card residency (
CardResidency,CardResidencyPlan): cards on screen are built at once, cards within 3 screens are built one per frame while the grid rests, cards past 4 screens are released. Scrolling never re-runs the grid's body. - Hidden grid (
DormantGate): while a page shows, the grid stays mounted but holds its updates, and the active card's content is not built under its page. overviewIdleChanged(_:): new source hook with a default no-op (additive; nothing public removed or changed). README updated.- Accessibility: a card outside the built band is a bare accessibility element in its slot (same label as the built card; activating opens the tab), so VoiceOver swiping reaches every tab.
Measurements (60 Hz iPhone 17 Pro simulator, iOS 26.5, list rig on aws-m4pro-6, before = feat-cmux-next at 4e28d9cf44d9, after = the app branch head, 2 runs each)
| Case | Scroll hitch ms/s (before / after) | Main CPU ms/s | Grid open, worst frame | Memory |
|---|---|---|---|---|
| 30 tabs | 0 / 0-1.5 | 213-265 / 160-167 | 540-584 / 86-317 ms | 185 / 59 MB |
| 30 tabs, one chat streaming | 173-396 / 0-1.7 | 930-1014 / 158-163 | 509-546 / 84 ms | 217-222 / 61 MB |
| 80 tabs | 18-75 / 0-5.2 | 469-709 / 204-227 | 679-779 / 79-92 ms | 395 / 66 MB |
The after numbers include the app-side host changes (stored tabs, per-tab observation, agent cards as pictures), which stay in the app branch.
Testing
swift testinPackages/iOS/CmuxTabsKiton aws-m4pro-5: 62 tests in 13 suites passed (newCardResidencyPlanTests).CmuxTabsKitDemobuilds for the iOS simulator (aws-m4pro-6, Xcode 26.6).- In the app:
WorkspaceTabsSourceListTests,WorkspaceTabsSourceUpdateTestson an iOS simulator, 16 passed.
Observed / Not run
- Observed: rig frame logs, videos and stills in the app PR's report; the demo host was built, not run.
- Not run: VoiceOver itself over the grid (the stand-in elements were checked in code only).
Changelog
none
🤖 Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
The tab grid now builds only cards near the screen and stays dormant while hidden, so scrolling and page updates never re-run the grid's body.
- Cards on screen build at once; cards within 3 screens build one per frame while the grid rests; cards past 4 screens are released.
- Unbuilt cards remain in the accessibility tree as bare elements with the same label, so VoiceOver reaches every tab.
- While a page shows, the grid stays mounted but holds parent updates (
DormantGate), and the active card's content is not built under its page. - Adds
overviewIdleChanged(_:)toTabsDataSourceas an additive default no-op; nothing public was removed or changed.