perf(renderer): index terminal unified tab reads (#8076)

This commit is contained in:
Neil 2026-07-10 20:51:28 -07:00 committed by GitHub
parent 09196ba086
commit 106009a90c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 61 additions and 40 deletions

View File

@ -180,7 +180,10 @@ import {
subscribeTerminalPaneAttention
} from './terminal-pane-attention-subscriptions'
import { getCachedTerminalTabForWorktree } from './terminal-tab-lookup'
import { getCachedTerminalGroupIdForWorktree } from './terminal-unified-tab-lookup'
import {
getCachedTerminalGroupIdForWorktree,
getCachedUnifiedTerminalTabForWorktree
} from './terminal-unified-tab-lookup'
import { resolveNativeChatLeafTitleAgent } from './native-chat-leaf-title-agent'
import { useRepoById } from '@/store/selectors'
import {
@ -655,23 +658,18 @@ export default function TerminalPane({
// communicates the presence-lock inside the chat surface instead (U9/R8).
const unifiedTabId = useAppStore(
(store) =>
(store.unifiedTabsByWorktree[worktreeId] ?? []).find(
(t) => t.contentType === 'terminal' && t.entityId === tabId
)?.id
getCachedUnifiedTerminalTabForWorktree(store.unifiedTabsByWorktree, worktreeId, tabId)?.id
)
const isChatViewMode = useAppStore(
(store) =>
(store.unifiedTabsByWorktree[worktreeId] ?? []).find(
(t) => t.contentType === 'terminal' && t.entityId === tabId
)?.viewMode === 'chat'
getCachedUnifiedTerminalTabForWorktree(store.unifiedTabsByWorktree, worktreeId, tabId)
?.viewMode === 'chat'
)
const nativeChatEnabled = useAppStore((store) => store.settings?.experimentalNativeChat === true)
const effectiveChatViewMode = nativeChatEnabled && isChatViewMode
const unifiedTabLabel = useAppStore(
(store) =>
(store.unifiedTabsByWorktree[worktreeId] ?? []).find(
(t) => t.contentType === 'terminal' && t.entityId === tabId
)?.label
getCachedUnifiedTerminalTabForWorktree(store.unifiedTabsByWorktree, worktreeId, tabId)?.label
)
const runtimePaneTitlesByPaneId = useAppStore(
useShallow((store) => store.runtimePaneTitlesByTabId[tabId] ?? {})

View File

@ -1,6 +1,9 @@
import { describe, expect, it, vi } from 'vitest'
import type { Tab } from '../../../../shared/types'
import { getCachedTerminalGroupIdForWorktree } from './terminal-unified-tab-lookup'
import {
getCachedTerminalGroupIdForWorktree,
getCachedUnifiedTerminalTabForWorktree
} from './terminal-unified-tab-lookup'
function makeTerminalTab(entityId: string, groupId: string): Tab {
return {
@ -45,8 +48,8 @@ function iterableTabs(tabs: Tab[]): {
}
}
describe('getCachedTerminalGroupIdForWorktree', () => {
it('reuses the terminal group lookup while the unified tab array is unchanged', () => {
describe('terminal unified tab lookup', () => {
it('shares one terminal lookup across all pane field and group reads', () => {
const tabs = [
makeEditorTab('editor-1'),
...Array.from({ length: 200 }, (_, index) =>
@ -56,14 +59,23 @@ describe('getCachedTerminalGroupIdForWorktree', () => {
const { value, iterator } = iterableTabs(tabs)
const unifiedTabsByWorktree = { 'wt-1': value }
expect(getCachedTerminalGroupIdForWorktree(unifiedTabsByWorktree, 'wt-1', 'terminal-199')).toBe(
'group-3'
)
for (let index = 0; index < 200; index += 1) {
const terminalTabId = `terminal-${index}`
expect(
getCachedUnifiedTerminalTabForWorktree(unifiedTabsByWorktree, 'wt-1', terminalTabId)
).toBe(tabs[index + 1])
expect(
getCachedUnifiedTerminalTabForWorktree(unifiedTabsByWorktree, 'wt-1', terminalTabId)?.id
).toBe(terminalTabId)
expect(
getCachedUnifiedTerminalTabForWorktree(unifiedTabsByWorktree, 'wt-1', terminalTabId)?.label
).toBe(terminalTabId)
}
expect(getCachedTerminalGroupIdForWorktree(unifiedTabsByWorktree, 'wt-1', 'terminal-0')).toBe(
'group-0'
)
expect(
getCachedTerminalGroupIdForWorktree(unifiedTabsByWorktree, 'wt-1', 'editor-1')
getCachedUnifiedTerminalTabForWorktree(unifiedTabsByWorktree, 'wt-1', 'editor-1')
).toBeNull()
expect(iterator).toHaveBeenCalledTimes(1)
@ -73,9 +85,9 @@ describe('getCachedTerminalGroupIdForWorktree', () => {
const first = iterableTabs([makeTerminalTab('terminal-1', 'group-a')])
const second = iterableTabs([makeTerminalTab('terminal-1', 'group-b')])
expect(getCachedTerminalGroupIdForWorktree({ 'wt-1': first.value }, 'wt-1', 'terminal-1')).toBe(
'group-a'
)
expect(
getCachedUnifiedTerminalTabForWorktree({ 'wt-1': first.value }, 'wt-1', 'terminal-1')?.groupId
).toBe('group-a')
expect(
getCachedTerminalGroupIdForWorktree({ 'wt-1': second.value }, 'wt-1', 'terminal-1')
).toBe('group-b')

View File

@ -1,29 +1,40 @@
import type { Tab } from '../../../../shared/types'
const terminalGroupLookupByUnifiedTabs = new WeakMap<readonly Tab[], Map<string, string>>()
const terminalTabLookupByUnifiedTabs = new WeakMap<readonly Tab[], Map<string, Tab>>()
export function getCachedUnifiedTerminalTabForWorktree(
unifiedTabsByWorktree: Record<string, Tab[]>,
worktreeId: string,
terminalTabId: string
): Tab | null {
const unifiedTabs = unifiedTabsByWorktree[worktreeId]
if (!unifiedTabs) {
return null
}
let lookup = terminalTabLookupByUnifiedTabs.get(unifiedTabs)
if (!lookup) {
// Why: every retained TerminalPane reads this tab on every store update.
// Share one immutable-array index instead of repeating linear scans.
lookup = new Map()
for (const tab of unifiedTabs) {
if (tab.contentType === 'terminal') {
lookup.set(tab.entityId, tab)
}
}
terminalTabLookupByUnifiedTabs.set(unifiedTabs, lookup)
}
return lookup.get(terminalTabId) ?? null
}
export function getCachedTerminalGroupIdForWorktree(
unifiedTabsByWorktree: Record<string, Tab[]>,
worktreeId: string,
terminalTabId: string
): string | null {
const unifiedTabs = unifiedTabsByWorktree[worktreeId]
if (!unifiedTabs) {
return null
}
let lookup = terminalGroupLookupByUnifiedTabs.get(unifiedTabs)
if (!lookup) {
// Why: every mounted TerminalPane asks for its owning group on store updates.
// Cache by immutable tab-array ref so 200 panes do not repeat the same scan.
lookup = new Map()
for (const tab of unifiedTabs) {
if (tab.contentType === 'terminal') {
lookup.set(tab.entityId, tab.groupId)
}
}
terminalGroupLookupByUnifiedTabs.set(unifiedTabs, lookup)
}
return lookup.get(terminalTabId) ?? null
return (
getCachedUnifiedTerminalTabForWorktree(unifiedTabsByWorktree, worktreeId, terminalTabId)
?.groupId ?? null
)
}