perf(dashboard): ignore unrelated store churn

This commit is contained in:
Brennan Benson
2026-07-20 16:54:26 -07:00
parent 65214acadf
commit 8abe115d99
3 changed files with 111 additions and 16 deletions
@@ -1,5 +1,6 @@
import { useMemo } from 'react'
import { useAppStore } from '@/store'
import { useShallow } from 'zustand/react/shallow'
import type { DashboardBucket } from '../../../../shared/dashboard-snapshot'
import { buildDashboardSnapshot } from './build-dashboard-snapshot'
@@ -13,19 +14,33 @@ const EMPTY_COUNTS: AgentBucketCounts = { attention: 0, working: 0, idle: 0 }
* only when an input slice changes (mirrors useDashboardData's cost profile).
*/
export function useAgentBucketCounts(): AgentBucketCounts {
const repos = useAppStore((s) => s.repos)
const worktreesByRepo = useAppStore((s) => s.worktreesByRepo)
const tabsByWorktree = useAppStore((s) => s.tabsByWorktree)
const agentStatusByPaneKey = useAppStore((s) => s.agentStatusByPaneKey)
const retainedAgentsByPaneKey = useAppStore((s) => s.retainedAgentsByPaneKey)
const migrationUnsupportedByPtyId = useAppStore((s) => s.migrationUnsupportedByPtyId)
const runtimeAgentOrchestrationByPaneKey = useAppStore(
(s) => s.runtimeAgentOrchestrationByPaneKey
const {
repos,
worktreesByRepo,
tabsByWorktree,
agentStatusByPaneKey,
retainedAgentsByPaneKey,
migrationUnsupportedByPtyId,
runtimeAgentOrchestrationByPaneKey,
terminalLayoutsByTabId,
ptyIdsByTabId,
runtimePaneTitlesByTabId,
agentStatusEpoch
} = useAppStore(
useShallow((s) => ({
repos: s.repos,
worktreesByRepo: s.worktreesByRepo,
tabsByWorktree: s.tabsByWorktree,
agentStatusByPaneKey: s.agentStatusByPaneKey,
retainedAgentsByPaneKey: s.retainedAgentsByPaneKey,
migrationUnsupportedByPtyId: s.migrationUnsupportedByPtyId,
runtimeAgentOrchestrationByPaneKey: s.runtimeAgentOrchestrationByPaneKey,
terminalLayoutsByTabId: s.terminalLayoutsByTabId,
ptyIdsByTabId: s.ptyIdsByTabId,
runtimePaneTitlesByTabId: s.runtimePaneTitlesByTabId,
agentStatusEpoch: s.agentStatusEpoch
}))
)
const terminalLayoutsByTabId = useAppStore((s) => s.terminalLayoutsByTabId)
const ptyIdsByTabId = useAppStore((s) => s.ptyIdsByTabId)
const runtimePaneTitlesByTabId = useAppStore((s) => s.runtimePaneTitlesByTabId)
const agentStatusEpoch = useAppStore((s) => s.agentStatusEpoch)
return useMemo(() => {
const snapshot = buildDashboardSnapshot(
@@ -34,7 +34,31 @@ vi.mock('@/lib/activate-tab-and-focus-pane', () => ({
activateTabAndFocusPane: vi.fn()
}))
import { useDashboardPopoutBridge } from './useDashboardPopoutBridge'
import {
dashboardSnapshotInputsChanged,
useDashboardPopoutBridge
} from './useDashboardPopoutBridge'
import type { DashboardSnapshotState } from './build-dashboard-snapshot'
import type { AppState } from '@/store/types'
type DashboardSnapshotWatchState = DashboardSnapshotState & Pick<AppState, 'agentStatusEpoch'>
function makeSnapshotWatchState(): DashboardSnapshotWatchState {
return {
repos: [],
worktreesByRepo: {},
tabsByWorktree: {},
agentStatusByPaneKey: {},
retainedAgentsByPaneKey: {},
migrationUnsupportedByPtyId: {},
runtimeAgentOrchestrationByPaneKey: {},
terminalLayoutsByTabId: {},
ptyIdsByTabId: {},
runtimePaneTitlesByTabId: {},
acknowledgedAgentsByPaneKey: {},
agentStatusEpoch: 0
}
}
function Harness({ enabled }: { enabled: boolean }): null {
useDashboardPopoutBridge(enabled)
@@ -80,6 +104,34 @@ describe('useDashboardPopoutBridge', () => {
expect(mocks.subscribeStore).not.toHaveBeenCalled()
})
it('ignores unrelated store writes while retaining every snapshot input', () => {
const previousState = makeSnapshotWatchState()
expect(dashboardSnapshotInputsChanged({ ...previousState }, previousState)).toBe(false)
const referenceInputs = [
'repos',
'worktreesByRepo',
'tabsByWorktree',
'agentStatusByPaneKey',
'retainedAgentsByPaneKey',
'migrationUnsupportedByPtyId',
'runtimeAgentOrchestrationByPaneKey',
'terminalLayoutsByTabId',
'ptyIdsByTabId',
'runtimePaneTitlesByTabId',
'acknowledgedAgentsByPaneKey'
] as const
for (const key of referenceInputs) {
expect(
dashboardSnapshotInputsChanged({ ...previousState, [key]: {} }, previousState),
key
).toBe(true)
}
expect(
dashboardSnapshotInputsChanged({ ...previousState, agentStatusEpoch: 1 }, previousState)
).toBe(true)
})
it('releases every dashboard listener when the experiment is disabled', async () => {
await act(async () => root.render(<Harness enabled />))
@@ -1,13 +1,36 @@
import { useEffect } from 'react'
import { useAppStore } from '@/store'
import { useAppStore, type AppState } from '@/store'
import { activateTabAndFocusPane } from '@/lib/activate-tab-and-focus-pane'
import { buildDashboardSnapshot } from './build-dashboard-snapshot'
import { buildDashboardSnapshot, type DashboardSnapshotState } from './build-dashboard-snapshot'
// Why: cap snapshot rebuilds during bursts of agent-status pings. The board is a
// glanceable surface, so ~4 updates/sec is plenty and keeps the cross-worktree
// rebuild off the hot path.
const PUBLISH_THROTTLE_MS = 250
type DashboardSnapshotWatchState = DashboardSnapshotState & Pick<AppState, 'agentStatusEpoch'>
export function dashboardSnapshotInputsChanged(
state: DashboardSnapshotWatchState,
previousState: DashboardSnapshotWatchState
): boolean {
return (
state.repos !== previousState.repos ||
state.worktreesByRepo !== previousState.worktreesByRepo ||
state.tabsByWorktree !== previousState.tabsByWorktree ||
state.agentStatusByPaneKey !== previousState.agentStatusByPaneKey ||
state.retainedAgentsByPaneKey !== previousState.retainedAgentsByPaneKey ||
state.migrationUnsupportedByPtyId !== previousState.migrationUnsupportedByPtyId ||
state.runtimeAgentOrchestrationByPaneKey !== previousState.runtimeAgentOrchestrationByPaneKey ||
state.terminalLayoutsByTabId !== previousState.terminalLayoutsByTabId ||
state.ptyIdsByTabId !== previousState.ptyIdsByTabId ||
state.runtimePaneTitlesByTabId !== previousState.runtimePaneTitlesByTabId ||
state.acknowledgedAgentsByPaneKey !== previousState.acknowledgedAgentsByPaneKey ||
// Why: freshness can change a bucket without replacing any backing map.
state.agentStatusEpoch !== previousState.agentStatusEpoch
)
}
/**
* Runs in the MAIN window (mount once in App). Two responsibilities:
* 1. While the pop-out dashboard is open, derive the snapshot from the live
@@ -88,7 +111,12 @@ export function useDashboardPopoutBridge(enabled: boolean): void {
open = next
if (open) {
if (!unsubscribeStore) {
unsubscribeStore = useAppStore.subscribe(publishThrottled)
unsubscribeStore = useAppStore.subscribe((state, previousState) => {
// Why: unrelated high-frequency store writes must not rebuild a cross-worktree snapshot.
if (dashboardSnapshotInputsChanged(state, previousState)) {
publishThrottled()
}
})
}
publishNow()
} else {