From d333b1fb422fe701db14bfe59ec4c8e2fb4e39f9 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Wed, 2 Sep 2026 13:14:34 -0700 Subject: [PATCH] perf(renderer): convert the four lazy-useRef sites that landed on main --- .../src/components/activity/use-agent-pane-threads.ts | 6 ++++-- .../src/components/dashboard/useAgentBucketCounts.ts | 3 ++- .../src/components/dashboard/useLiveDashboardSnapshot.ts | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/renderer/src/components/activity/use-agent-pane-threads.ts b/src/renderer/src/components/activity/use-agent-pane-threads.ts index 01eb0475a02..1934488439e 100644 --- a/src/renderer/src/components/activity/use-agent-pane-threads.ts +++ b/src/renderer/src/components/activity/use-agent-pane-threads.ts @@ -121,8 +121,10 @@ export function useAgentPaneThreads(args: { // identities across rebuilds, so a status write to one agent leaves every other row's // memo bail-out and cached search text intact. Rebuilds are deterministic, so a repeated // (StrictMode/deferred) memo invocation returns identical objects from the cache. - const eventBuildCacheRef = useRef(createActivityEventBuildCache()) - const threadReuseCacheRef = useRef(createAgentPaneThreadReuseCache()) + const eventBuildCacheRef = useRef>(undefined!) + eventBuildCacheRef.current ??= createActivityEventBuildCache() + const threadReuseCacheRef = useRef>(undefined!) + threadReuseCacheRef.current ??= createAgentPaneThreadReuseCache() const { events: allEvents, liveAgentByPaneKey } = useMemo( () => diff --git a/src/renderer/src/components/dashboard/useAgentBucketCounts.ts b/src/renderer/src/components/dashboard/useAgentBucketCounts.ts index 60df4995e56..0e8c2881244 100644 --- a/src/renderer/src/components/dashboard/useAgentBucketCounts.ts +++ b/src/renderer/src/components/dashboard/useAgentBucketCounts.ts @@ -51,7 +51,8 @@ export function useAgentBucketCounts(): AgentBucketCounts { // Why a per-hook cache: unrelated status/title writes change one worktree's inputs; // the cache keeps every other worktree's counts without rerunning its row pipeline. - const cacheRef = useRef(createDashboardBucketCountsCache()) + const cacheRef = useRef>(undefined!) + cacheRef.current ??= createDashboardBucketCountsCache() return useMemo(() => { return buildDashboardBucketCounts( { diff --git a/src/renderer/src/components/dashboard/useLiveDashboardSnapshot.ts b/src/renderer/src/components/dashboard/useLiveDashboardSnapshot.ts index 227cf4e3f8b..52270167ef9 100644 --- a/src/renderer/src/components/dashboard/useLiveDashboardSnapshot.ts +++ b/src/renderer/src/components/dashboard/useLiveDashboardSnapshot.ts @@ -11,7 +11,8 @@ import { createWorktreeAgentRowsCache } from './worktree-agent-rows-cache' * is no relay, so we derive it here from the same builder the bridge uses. */ export function useLiveDashboardSnapshot(): DashboardSnapshot { - const rowsCacheRef = useRef(createWorktreeAgentRowsCache()) + const rowsCacheRef = useRef>(undefined!) + rowsCacheRef.current ??= createWorktreeAgentRowsCache() const repos = useAppStore((s) => s.repos) const worktreesByRepo = useAppStore((s) => s.worktreesByRepo) const tabsByWorktree = useAppStore((s) => s.tabsByWorktree)