-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Summary
A codebase review identified JavaScript performance patterns that can be improved. The most impactful are Array.includes() calls inside loops (O(n²) instead of O(n)), mutating .sort() where .toSorted() is preferred for immutability, and multiple array iterations that could be combined.
Note: React version is 18.3.1 — React 19 API findings (
forwardRef,use()) are listed as future-proofing items for when the upgrade happens.
Findings
1. Array.includes() inside loops — should use Set — MEDIUM
| File | Line | Pattern | Impact |
|---|---|---|---|
App.tsx |
82 | allIds.filter(id => !currentOrder.includes(id)) |
Runs on every session change. Line 80 already creates allIdSet — apply same pattern to currentOrder |
stores/useWorkspaceStore.ts |
363 | sessionIds.filter(id => validSessionIds.includes(id)) inside .map() |
O(tabs × sessionIds × validSessionIds). Called during rehydration |
components/shared/UsagePopover.tsx |
143 | sessions.filter(s => activeTab.sessionIds.includes(s.id)) |
Runs inside useMemo on every session/tab change |
lib/plugin-theme-injector.ts |
136 | (ALL_THEMES as string[]).includes(themeId) |
40+ element array. Easy fix — wrap in a static Set at module level |
Fix pattern:
const validSet = new Set(validSessionIds);
const filtered = sessionIds.filter(id => validSet.has(id));2. Mutating .sort() — prefer .toSorted() — LOW
All instances operate on freshly-created local arrays so they're safe in practice, but .toSorted() is more defensive and idiomatic.
| File | Line | Context |
|---|---|---|
components/settings/SettingsNavigation.tsx |
108 | catSections.sort(...) |
components/settings/SettingsNavigation.tsx |
127 | pluginGroups.sort(...) |
components/plugin/ExtensionSlot.tsx |
75 | matches.sort(...) |
components/plugin/ExtensionSlot.tsx |
94 | matches.sort(...) |
components/shared/UsagePopover.tsx |
169 | panels.sort(...) |
Note: Verify
tsconfig.jsonlibincludes ES2023 before using.toSorted().
3. Multiple array iterations — LOW
| File | Lines | Pattern |
|---|---|---|
components/shared/BranchSelector.tsx |
54-62 | Triple iteration: filter() + two more filter()s to partition local/remote. Also calls searchQuery.toLowerCase() per branch instead of once |
components/shared/BranchAutocomplete.tsx |
64-72 | Double filter() outside useMemo — runs on every render even when data hasn't changed |
Fix: Combine into single loop that partitions into local/remote:
const { local, remote } = useMemo(() => {
const lower = search.toLowerCase();
const local: Branch[] = [], remote: Branch[] = [];
for (const b of branches) {
if (search && !b.name.toLowerCase().includes(lower)) continue;
(b.isRemote ? remote : local).push(b);
}
return { local, remote };
}, [branches, search]);4. Early exit optimization — LOW
File: components/terminal/SessionStatusDisplay.tsx (lines 26-49)
getModeConfig() does [...statusRenderers.values()].find() and providers.find() before checking if (aiMode === 'plain') — those results are discarded for the 'plain' case. Move the 'plain' check to the top.
5. React 19 future-proofing (no action needed now)
forwardRef usage: 14 files with ~35 forwardRef calls, mostly in components/ui/ (shadcn/ui). When upgrading to React 19, these can use ref as a regular prop. Wait for shadcn to ship React 19-compatible templates.
useContext usage: Zero instances found — the codebase uses Zustand exclusively. No migration needed.
Checklist
Quick wins:
- Convert
currentOrdertoSetinApp.tsx:82 - Convert
validSessionIdstoSetinuseWorkspaceStore.ts:357-368 - Convert
activeTab.sessionIdstoSetinUsagePopover.tsx:143 - Create static
SetfromALL_THEMESinplugin-theme-injector.ts - Move
'plain'early return beforefind()calls inSessionStatusDisplay.tsx
Low priority:
- Replace
.sort()with.toSorted()in 5 locations (verify ES2023 support first) - Combine filter+partition in
BranchSelector.tsxandBranchAutocomplete.tsxinto single loop insideuseMemo - Track React 19 upgrade for
forwardRefremoval (blocked on shadcn/ui compatibility)
Verification
pnpm typecheckandpnpm test- For
Setconversions: improvements are algorithmic, no benchmarking needed at current scale - For
.toSorted(): verifytsconfig.jsonhas"lib": ["ES2023"]or similar