Skip to content

Sidebar: allocation-free Hashable render-item id (hottest app frame in 5764 spindump) - #6021

Closed
azooz2003-bit wants to merge 2 commits into
mainfrom
issue-5764-renderitem-id
Closed

azooz2003-bit wants to merge 2 commits into
mainfrom
issue-5764-renderitem-id

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented Jun 12, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

ForEach(renderItems, id: \.id) gathers every row's identifier on each sidebar list diff, and the sidebar currently re-diffs all rows per update. SidebarWorkspaceRenderItem.id was a computed String ("workspace.\(uuid.uuidString)") that allocates and formats a fresh string on every getter call. In the #5764 livelock spindump, SidebarWorkspaceRenderItem.id.getter is the hottest app-owned frame (plus initializeWithCopy/destroy for SidebarWorkspaceRenderItem), so this cost multiplies every pass of the layout loop and every normal scroll/diff.

Fix

SidebarWorkspaceRenderItemID, a two-case Hashable enum over UUID (.group(UUID) / .workspace(UUID)): identity compare and hash with zero heap allocation. The case keeps group headers and workspace rows from colliding on the same UUID, the same guarantee the string prefixes gave. Identity values are unchanged in meaning, so row lifetime, state, and animations are unaffected.

Safety audit: the only consumers of .id are the ForEach key path (Sources/ContentView.swift:12535) and nothing else; scrollTo targets the explicit inner .id(tab.id) UUIDs registered on row views, not the ForEach identity, and no code persists the string form. WWDC rule backing: identifiers must be cheap to create because they are gathered often (WWDC23 Demystify SwiftUI performance, https://developer.apple.com/videos/play/wwdc2023/10160/).

This is the per-pass cost companion to the structural loop fix in #6019; the two are independent and merge in either order.

Related: #5764, #5845, #2586.

Note on tests: existing WorkspaceGroupTests cover renderItems semantics and pass unchanged; an id-shape unit test would be a source-shape assertion with no behavioral value, so none is added. Preflighted on tag rid: 5 workspaces + a workspace group (exercises both id cases), simulated sidebar drags, rows/group header/selection all render and respond.

🤖 Generated with Claude Code


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Replaces the sidebar render-item String id with an allocation-free Hashable enum to cut per-pass diff cost and scrolling overhead. Addresses #5764; no behavior changes.

  • Performance
    • Introduced SidebarWorkspaceRenderItemID with .group(UUID) and .workspace(UUID) for zero-allocation identity and hashing.
    • Preserves distinct identities and behavior: ForEach(..., id: \.id), row state/animations, and scrollTo targets remain unchanged.

Written for commit 83322e5. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

Release Notes

  • Refactor
    • Improved sidebar rendering stability by implementing a more robust item identification system for workspace groups and individual workspace items.

…le enum

ForEach(renderItems, id: \.id) gathers every row's identifier on each list
diff, and the sidebar re-diffs all rows per update. The previous computed
String id ("workspace.\(uuid.uuidString)") allocated and formatted a fresh
36-char string per access; SidebarWorkspaceRenderItem.id.getter was the
hottest app-owned frame in the
#5764 livelock spindump.

SidebarWorkspaceRenderItemID is a two-case enum over UUID: identity compare
and hash with zero heap allocation, and group headers can never collide with
workspace rows on the same UUID (same guarantee the string prefixes gave).
Identity values are unchanged in meaning, so row lifetime and animations are
unaffected; nothing persisted the string form (the only consumers are the
ForEach key path and scrollTo, which targets the explicit inner .id(tab.id)
UUIDs, not the ForEach identity).

Pure per-pass cost cut for #5764,
#5845,
#2586; complements the structural
loop fix in #6019.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 12, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 13, 2026 1:31am
cmux-staging Building Building Preview, Comment Jun 13, 2026 1:31am

@azooz2003-bit

Copy link
Copy Markdown
Collaborator Author

@codex review

@coderabbitai

coderabbitai Bot commented Jun 12, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The SidebarWorkspaceRenderItem enum now uses a type-safe, collision-free identity system. A new SidebarWorkspaceRenderItemID enum replaces string-based identities, with distinct cases for group headers and workspace rows indexed by their respective UUIDs.

Changes

Sidebar Identity Type Safety

Layer / File(s) Summary
Typed identity enum and id property
Sources/SidebarWorkspaceRenderItem.swift
New SidebarWorkspaceRenderItemID enum with group(UUID) and workspace(UUID) cases replaces the string-based id property, ensuring stable, non-colliding identities for group headers and workspace rows.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

A rabbit hops through sidebar rows, ✨
Where groups and workspaces now glow,
With UUIDs typed and true,
No string collisions to pursue,
Safe identities all the way down! 🐰

🚥 Pre-merge checks | ✅ 21
✅ Passed checks (21 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: replacing a String-based id with an allocation-free Hashable enum, and references the performance issue (hottest frame in spindump 5764) that motivates the change.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed PR change is confined to SidebarWorkspaceRenderItem.swift: a new top-level Hashable enum ID and id getter return; no new @MainActor-by-default value models, service protocols, Sendable reference ty...
Cmux Swift Blocking Runtime ✅ Passed PR #6021 changes only Sources/SidebarWorkspaceRenderItem.swift (id String→Hashable enum) and contains no DispatchSemaphore waits, sleeps, main-queue sync, or manual locks.
Cmux Expensive Synchronous Load ✅ Passed PR changes only Sources/SidebarWorkspaceRenderItem.swift; it adds SidebarWorkspaceRenderItemID enum and contains 0 matches for RestorableAgentSessionIndex.load, sysctl, or SharedLiveAgentIndex.shar...
Cmux Cache Substitution Correctness ✅ Passed PR #6021 only changes SidebarWorkspaceRenderItem.id to a typed Hashable enum; no persistence/history/undo/snapshot or cached-value substitution is present (rules concern cache staleness).
Cmux No Hacky Sleeps ✅ Passed PR #6021 only changes Sources/SidebarWorkspaceRenderItem.swift; no TypeScript/JS/shell/non-Swift runtime scripts were modified, so no hacky sleeps were introduced.
Cmux Algorithmic Complexity ✅ Passed PR changes SidebarWorkspaceRenderItem id from computed String to Hashable enum; no new nested scans/sorts/filters in sidebar renderItems loops (only O(n) iteration + Set/dict lookups).
Cmux Swift Concurrency ✅ Passed PR #6021 changes only Sources/SidebarWorkspaceRenderItem.swift (String id -> Hashable enum); no new legacy async patterns (DispatchQueue/Combine/@Published/Task/fire-and-forget/completion handlers)...
Cmux Swift @Concurrent ✅ Passed PR changes Sources/SidebarWorkspaceRenderItem.swift only; inspected updated file: no async/nonisolated async or @concurrent introduced, so swift-concurrent-annotation rule isn’t violated.
Cmux Swift File And Package Boundaries ✅ Passed Only Sources/SidebarWorkspaceRenderItem.swift was involved; it’s ~85 lines, imports Foundation only, and contains no mixed UI/state/persistence/network/parsing/protocol responsibilities or package-...
Cmux Swift Logging ✅ Passed Checked Sources/SidebarWorkspaceRenderItem.swift: no print/debugPrint/dump/NSLog, no file-scoped Logger additions; matches swift-logging.md fail conditions.
Cmux User-Facing Error Privacy ✅ Passed Diff only swaps SidebarWorkspaceRenderItem.id from String to SidebarWorkspaceRenderItemID enum; no user-facing error/alert/recovery text added per user-facing-errors rules.
Cmux Full Internationalization ✅ Passed Inspected SidebarWorkspaceRenderItem.swift: only identity changed to Hashable enum; no Text/localized Swift strings or web/i18n message/cat updates present.
Cmux Swiftui State Layout ✅ Passed SidebarWorkspaceRenderItem.swift now defines SidebarWorkspaceRenderItemID(Hashable) and returns typed .id cases; no ObservableObject/@published, GeometryReader, or render-time state mutations were...
Cmux Architecture Rethink ✅ Passed git diff origin/main..HEAD --name-only shows only Sources/SidebarWorkspaceRenderItem.swift changed; it only introduces a Hashable enum for id and has no sleeps/polling/locks/observers/timers.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR only updates SidebarWorkspaceRenderItem id to Hashable enum; changed file contains no NSWindow/NSPanel/Window/WindowGroup/NSWindowController and no cmuxAuxiliaryWindowIdentifiers usage, so the a...
Cmux Source Artifacts ✅ Passed GitHub PR diff shows only Sources/SidebarWorkspaceRenderItem.swift changed; its contents are Swift source, with no added generated logs/caches/build artifacts.
Description check ✅ Passed The PR description is well-structured and comprehensive. It includes a clear problem statement, the fix approach, safety audit, testing notes, and relevant issue links, though some template sections are missing or incomplete.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-5764-renderitem-id

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@greptile-apps

greptile-apps Bot commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Replaces the computed String id on SidebarWorkspaceRenderItem with SidebarWorkspaceRenderItemID, a two-case Hashable enum over UUID, eliminating per-call string allocation and formatting in the ForEach identity path.

  • SidebarWorkspaceRenderItemID is a new enum with .group(UUID) and .workspace(UUID) cases; Hashable conformance is synthesized and delegates directly to UUID.hashValue, so identity gathering is now a zero-allocation integer compare.
  • The old string prefixes ("group." / "workspace.") that prevented cross-kind UUID collisions are replaced by the enum discriminant, preserving the same uniqueness guarantee with no behavioral change for ForEach, scrollTo, row state, or animations.

Confidence Score: 5/5

Safe to merge. The change is a pure type substitution in a single file with no behavioral side effects.

The new SidebarWorkspaceRenderItemID enum is a plain value type with synthesized Hashable conformance; it carries no mutable state, needs no actor isolation, and cannot cross a trust boundary. The id property on SidebarWorkspaceRenderItem inherits @MainActor from the enclosing type, so all associated-value accesses remain correctly isolated. The enum discriminant replaces the old string prefix with the same collision-prevention guarantee. No other file is touched and no public API surface changes.

No files require special attention.

Important Files Changed

Filename Overview
Sources/SidebarWorkspaceRenderItem.swift Introduces SidebarWorkspaceRenderItemID enum and replaces the String-returning id property with it; change is minimal, correct, and well-documented.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[SwiftUI list diff triggered] --> B["ForEach gathers row IDs via id: \.id"]
    B --> C{SidebarWorkspaceRenderItem case}
    C -->|groupHeader| D["group(group.id)"]
    C -->|workspace| E["workspace(workspace.id)"]
    D --> F[SidebarWorkspaceRenderItemID - stack-allocated enum]
    E --> F
    F --> G[Synthesized Hashable delegates to UUID.hashValue]
    G --> H[Diff result - zero heap allocation per row]
Loading

Reviews (2): Last reviewed commit: "Merge origin/main (pick up workflow-guar..." | Re-trigger Greptile

@azooz2003-bit

Copy link
Copy Markdown
Collaborator Author

Superseded by the combined PR #6033 (this PR's change is included verbatim there), opened to run a single CI/review/dogfood pass across all three sidebar-perf fixes. Closing; track 6033.

This branch was successfully deployed

1 active deployment
Preview – cmux — 83322e5a Deployed Jun 13, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant