perf(renderer): skip the resume cache sweep publication when nothing changed

Every eviction helper already returns its input reference untouched when it
evicts nothing, so the opening sweep in refreshAllGitHub can compare identities
and return the previous state. Window resume then stops waking every store
subscriber on a no-op sweep.

Folds in the remaining unique optimization from #13711, which this PR
supersedes on the lookup-indexing side.

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Neil
2026-08-10 21:36:40 -07:00
co-authored by Orca
parent 49ba9c571e
commit 5408439e07
2 changed files with 62 additions and 9 deletions
@@ -5428,6 +5428,46 @@ describe('createGitHubSlice.refreshAllGitHub', () => {
resetRemoteRuntimeMocks()
})
it('publishes no store update when the cache sweep changes nothing', () => {
const store = createTestStore()
store.setState({
repos: [{ id: 'repo-1', path: '/repo', name: 'repo', kind: 'git' }],
groupBy: 'repo',
worktreeCardProperties: ['comment'],
rightSidebarOpen: false,
worktreesByRepo: { 'repo-1': [makePRRefreshWorktree()] }
} as unknown as Partial<AppState>)
let publications = 0
const unsubscribe = store.subscribe(() => {
publications += 1
})
store.getState().refreshAllGitHub()
unsubscribe()
expect(publications).toBe(0)
})
it('still clears populated comments when no workspace refresh is needed', () => {
const store = createTestStore()
store.setState({
commentsCache: { cached: { data: [], fetchedAt: 1 } },
groupBy: 'repo',
worktreeCardProperties: ['comment'],
rightSidebarOpen: false
} as unknown as Partial<AppState>)
let publications = 0
const unsubscribe = store.subscribe(() => {
publications += 1
})
store.getState().refreshAllGitHub()
unsubscribe()
expect(store.getState().commentsCache).toEqual({})
expect(publications).toBe(1)
})
it('skips repo and worktree identity reads when no GitHub decoration is visible', () => {
const store = createTestStore()
const repoId = 'repo-idle'
+22 -9
View File
@@ -4433,15 +4433,28 @@ export const createGitHubSlice: StateCreator<AppState, [], [], GitHubSlice> = (s
refreshAllGitHub: () => {
// Clear comments cache; evict stale entries to bound long-session growth across repos/branches.
set((s) => ({
commentsCache: {},
prCache: evictStaleEntries(s.prCache),
issueCache: evictStaleEntries(s.issueCache),
checksCache: evictStaleEntries(s.checksCache),
workItemsCache: evictStaleEntries(s.workItemsCache),
projectViewCache: evictStaleEntries(s.projectViewCache),
prRefreshStates: pruneExpiredPRRefreshStates(s.prRefreshStates)
}))
set((s) => {
const next = {
commentsCache: Object.keys(s.commentsCache).length === 0 ? s.commentsCache : {},
prCache: evictStaleEntries(s.prCache),
issueCache: evictStaleEntries(s.issueCache),
checksCache: evictStaleEntries(s.checksCache),
workItemsCache: evictStaleEntries(s.workItemsCache),
projectViewCache: evictStaleEntries(s.projectViewCache),
prRefreshStates: pruneExpiredPRRefreshStates(s.prRefreshStates)
}
// Why: each eviction helper returns its input untouched when nothing changed, so an
// unchanged sweep can return `s` and avoid waking every subscriber on window resume.
return next.commentsCache === s.commentsCache &&
next.prCache === s.prCache &&
next.issueCache === s.issueCache &&
next.checksCache === s.checksCache &&
next.workItemsCache === s.workItemsCache &&
next.projectViewCache === s.projectViewCache &&
next.prRefreshStates === s.prRefreshStates
? s
: next
})
// Why: don't prune prRequestGenerations here — deleting a live generation makes its response look stale.