From 17ee56862e29a620ca0e091ccfd5716a72048054 Mon Sep 17 00:00:00 2001
From: Neil <4138956+nwparker@users.noreply.github.com>
Date: Sat, 30 May 2026 07:20:02 -0700
Subject: [PATCH] perf: handle large workspace space size scales
---
.../status-bar/WorkspaceSpaceManagerPanel.tsx | 6 ++--
.../workspace-space-presentation.test.ts | 19 ++++++++++++
.../workspace-space-presentation.ts | 29 ++++++++++++++++++-
3 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/src/renderer/src/components/status-bar/WorkspaceSpaceManagerPanel.tsx b/src/renderer/src/components/status-bar/WorkspaceSpaceManagerPanel.tsx
index adf5a28f2e8..0fa98ec3ac6 100644
--- a/src/renderer/src/components/status-bar/WorkspaceSpaceManagerPanel.tsx
+++ b/src/renderer/src/components/status-bar/WorkspaceSpaceManagerPanel.tsx
@@ -66,6 +66,8 @@ import { buildTreemapLayout, type TreemapRect } from './workspace-space-layout'
import {
filterWorkspaceSpaceRows,
countWorkspaceSpaceActiveAgents,
+ getLargestWorkspaceSpaceItemSize,
+ getLargestWorkspaceSpaceRowSize,
getSelectedDeletableWorkspaceIds,
getVisibleDeletableWorkspaceIds,
getWorkspaceSpaceGitStatusRefreshCandidates,
@@ -831,7 +833,7 @@ function BreakdownList({
)
}
- const maxChildSize = Math.max(...worktree.topLevelItems.map((item) => item.sizeBytes), 0)
+ const maxChildSize = getLargestWorkspaceSpaceItemSize(worktree.topLevelItems)
const topLevelItemCount = worktree.topLevelItems.length + worktree.omittedTopLevelItemCount
return (
@@ -1276,7 +1278,7 @@ export function WorkspaceSpaceManagerPanel(): React.JSX.Element {
const zoomedWorktree =
sourceRows.find((row) => row.worktreeId === treemapZoomWorktreeId && row.status === 'ok') ??
null
- const maxSize = Math.max(...rows.map((row) => row.sizeBytes), 0)
+ const maxSize = getLargestWorkspaceSpaceRowSize(rows)
const selectedDeletableIds = useMemo(
() => getSelectedDeletableWorkspaceIds(rows, selectedIds, isWorktreeUnavailableForDelete),
[isWorktreeUnavailableForDelete, rows, selectedIds]
diff --git a/src/renderer/src/components/status-bar/workspace-space-presentation.test.ts b/src/renderer/src/components/status-bar/workspace-space-presentation.test.ts
index 8d52d451f00..3fe0be6b74a 100644
--- a/src/renderer/src/components/status-bar/workspace-space-presentation.test.ts
+++ b/src/renderer/src/components/status-bar/workspace-space-presentation.test.ts
@@ -3,6 +3,8 @@ import type { WorkspaceSpaceWorktree } from '../../../../shared/workspace-space-
import {
countWorkspaceSpaceActiveAgents,
filterWorkspaceSpaceRows,
+ getLargestWorkspaceSpaceItemSize,
+ getLargestWorkspaceSpaceRowSize,
getSelectedDeletableWorkspaceIds,
getVisibleDeletableWorkspaceIds,
getWorkspaceSpaceGitStatusRefreshCandidates,
@@ -99,6 +101,23 @@ describe('workspace space presentation helpers', () => {
expect(filterWorkspaceSpaceRows(rows, '', true).map((item) => item.worktreeId)).toEqual(['a'])
})
+ it('finds largest sizes without spreading large workspace arrays', () => {
+ const rows = Array.from({ length: 130_000 }, (_, index) =>
+ row({ worktreeId: `wt-${index}`, sizeBytes: index === 87_654 ? 999_999 : index })
+ )
+ const items = Array.from({ length: 130_000 }, (_, index) => ({
+ name: `item-${index}`,
+ path: `/repo/item-${index}`,
+ kind: 'directory' as const,
+ sizeBytes: index === 12_345 ? 888_888 : index
+ }))
+
+ expect(getLargestWorkspaceSpaceRowSize(rows)).toBe(999_999)
+ expect(getLargestWorkspaceSpaceItemSize(items)).toBe(888_888)
+ expect(getLargestWorkspaceSpaceRowSize([])).toBe(0)
+ expect(getLargestWorkspaceSpaceItemSize([])).toBe(0)
+ })
+
it('returns only selected worktrees that can be deleted', () => {
const rows = [
row({ worktreeId: 'ok', canDelete: true, status: 'ok' }),
diff --git a/src/renderer/src/components/status-bar/workspace-space-presentation.ts b/src/renderer/src/components/status-bar/workspace-space-presentation.ts
index 5a8edcd35f9..28efd04b67f 100644
--- a/src/renderer/src/components/status-bar/workspace-space-presentation.ts
+++ b/src/renderer/src/components/status-bar/workspace-space-presentation.ts
@@ -7,7 +7,10 @@ import {
} from '../../../../shared/agent-status-types'
import { parsePaneKey } from '../../../../shared/stable-pane-id'
import type { TerminalTab } from '../../../../shared/types'
-import type { WorkspaceSpaceWorktree } from '../../../../shared/workspace-space-types'
+import type {
+ WorkspaceSpaceItem,
+ WorkspaceSpaceWorktree
+} from '../../../../shared/workspace-space-types'
export type WorkspaceSpaceSortKey = 'size' | 'name' | 'repo' | 'activity'
export type WorkspaceSpaceSortDirection = 'asc' | 'desc'
@@ -140,6 +143,30 @@ export function getWorkspaceSpaceSearchText(worktree: WorkspaceSpaceWorktree): s
.toLowerCase()
}
+export function getLargestWorkspaceSpaceItemSize(
+ items: readonly Pick[]
+): number {
+ let maxSize = 0
+ for (const item of items) {
+ if (item.sizeBytes > maxSize) {
+ maxSize = item.sizeBytes
+ }
+ }
+ return maxSize
+}
+
+export function getLargestWorkspaceSpaceRowSize(
+ rows: readonly Pick[]
+): number {
+ let maxSize = 0
+ for (const row of rows) {
+ if (row.sizeBytes > maxSize) {
+ maxSize = row.sizeBytes
+ }
+ }
+ return maxSize
+}
+
function compareRows(
left: WorkspaceSpaceWorktree,
right: WorkspaceSpaceWorktree,