Skip to content

Commit c41e339

Browse files
authored
perf: cache sidebar branch/dir/PR snapshot off the per-keystroke title path (#20) (#43)
1 parent d0fe6fa commit c41e339

1 file changed

Lines changed: 44 additions & 15 deletions

File tree

Sources/ContentView.swift

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12441,6 +12441,13 @@ private struct TabItemView: View, Equatable {
1244112441
@State private var workspaceObservationGeneration: UInt64 = 0
1244212442
@State private var isHovering = false
1244312443
@State private var rowHeight: CGFloat = 1
12444+
// Cached results of the expensive bonsplit tree walk + branch/dir/PR snapshot.
12445+
// Updated only by the debounced publisher, onAppear, and settings changes —
12446+
// NOT by the immediate publisher (title keystrokes). This prevents the tree
12447+
// walk from running on every keystroke in single-panel workspaces.
12448+
@State private var cachedOrderedPanelIds: [UUID]? = nil
12449+
@State private var cachedBranchDirectoryLines: [VerticalBranchDirectoryLine] = []
12450+
@State private var cachedPullRequestRows: [PullRequestDisplay] = []
1244412451

1244512452
var isMultiSelected: Bool {
1244612453
selectedTabIds.contains(tab.id)
@@ -12681,9 +12688,11 @@ private struct TabItemView: View, Equatable {
1268112688
let latestNotificationSubtitle = latestNotificationText
1268212689
let effectiveSubtitle = latestNotificationSubtitle
1268312690
let detailVisibility = visibleAuxiliaryDetails
12684-
let orderedPanelIds: [UUID]? = (detailVisibility.showsBranchDirectory || detailVisibility.showsPullRequests)
12685-
? tab.sidebarOrderedPanelIds()
12686-
: nil
12691+
// Read from cache — updated only by the debounced publisher, onAppear,
12692+
// and settings changes. Title-keystroke re-renders skip this tree walk.
12693+
let orderedPanelIds: [UUID]? = cachedOrderedPanelIds
12694+
let branchDirectoryLines: [VerticalBranchDirectoryLine] = cachedBranchDirectoryLines
12695+
let pullRequestRows: [PullRequestDisplay] = cachedPullRequestRows
1268712696
let compactGitBranchSummaryText: String? = {
1268812697
guard detailVisibility.showsBranchDirectory,
1268912698
!sidebarBranchVerticalLayout,
@@ -12705,19 +12714,7 @@ private struct TabItemView: View, Equatable {
1270512714
gitSummary: compactGitBranchSummaryText,
1270612715
directorySummary: compactDirectorySummaryText
1270712716
)
12708-
let branchDirectoryLines: [VerticalBranchDirectoryLine] = {
12709-
guard detailVisibility.showsBranchDirectory,
12710-
sidebarBranchVerticalLayout,
12711-
let orderedPanelIds else {
12712-
return []
12713-
}
12714-
return verticalBranchDirectoryLines(orderedPanelIds: orderedPanelIds)
12715-
}()
1271612717
let branchLinesContainBranch = sidebarShowGitBranch && branchDirectoryLines.contains { $0.branch != nil }
12717-
let pullRequestRows: [PullRequestDisplay] = {
12718-
guard detailVisibility.showsPullRequests, let orderedPanelIds else { return [] }
12719-
return pullRequestDisplays(orderedPanelIds: orderedPanelIds)
12720-
}()
1272112718

1272212719
VStack(alignment: .leading, spacing: 4) {
1272312720
HStack(spacing: 8) {
@@ -13056,6 +13053,10 @@ private struct TabItemView: View, Equatable {
1305613053
"desc=\"\(debugCommandPaletteTextPreview(description))\""
1305713054
)
1305813055
#endif
13056+
// Refresh expensive caches (tree walk, branch/dir/PR) before
13057+
// signalling a redraw. The immediate publisher intentionally does
13058+
// NOT call this so that title keystrokes skip the tree walk.
13059+
recomputeSidebarDetailCache()
1305913060
workspaceObservationGeneration &+= 1
1306013061
}
1306113062
.onDrag {
@@ -13098,6 +13099,15 @@ private struct TabItemView: View, Equatable {
1309813099
.accessibilityAction(named: Text(moveDownActionText)) {
1309913100
moveBy(1)
1310013101
}
13102+
.onAppear {
13103+
// Prime the cache so branch/dir/PR rows appear immediately,
13104+
// before the first debounced publisher fires.
13105+
recomputeSidebarDetailCache()
13106+
}
13107+
.onChange(of: visibleAuxiliaryDetails) { _ in
13108+
// Toggling branch/PR columns changes which data we need to cache.
13109+
recomputeSidebarDetailCache()
13110+
}
1310113111
.contextMenu { workspaceContextMenu }
1310213112
}
1310313113

@@ -13669,6 +13679,25 @@ private struct TabItemView: View, Equatable {
1366913679
let directory: String?
1367013680
}
1367113681

13682+
/// Recomputes the expensive sidebar detail caches (bonsplit tree walk,
13683+
/// branch/directory lines, PR snapshot) and writes them into @State.
13684+
/// Must be called only from the debounced publisher, onAppear, and
13685+
/// settings-change handlers — never from the immediate (title) publisher.
13686+
private func recomputeSidebarDetailCache() {
13687+
let detail = visibleAuxiliaryDetails
13688+
let needsDetail = detail.showsBranchDirectory || detail.showsPullRequests
13689+
let ids: [UUID]? = needsDetail ? tab.sidebarOrderedPanelIds() : nil
13690+
cachedOrderedPanelIds = ids
13691+
cachedBranchDirectoryLines = {
13692+
guard detail.showsBranchDirectory, sidebarBranchVerticalLayout, let ids else { return [] }
13693+
return verticalBranchDirectoryLines(orderedPanelIds: ids)
13694+
}()
13695+
cachedPullRequestRows = {
13696+
guard detail.showsPullRequests, let ids else { return [] }
13697+
return pullRequestDisplays(orderedPanelIds: ids)
13698+
}()
13699+
}
13700+
1367213701
private func verticalBranchDirectoryLines(orderedPanelIds: [UUID]) -> [VerticalBranchDirectoryLine] {
1367313702
let entries = tab.sidebarBranchDirectoryEntriesInDisplayOrder(orderedPanelIds: orderedPanelIds)
1367413703
let home = SidebarPathFormatter.homeDirectoryPath

0 commit comments

Comments
 (0)