Skip to content

perf(renderer): subscribe panes per session and add memo boundaries instead of re-rendering the whole tree per frame #763

Description

@Juliusolsson05

Symptom

useWorkspace() (src/renderer/src/workspace/hook/index.ts:100) selects the entire workspaceRuntimes map and returns a fresh unmemoised object every render (hook/index.ts:897-1021App.tsx:87WorkspaceContext.tsx:11-17). Every setRuntimes (app-state/workspace/slice.ts:48-51, new map identity per screen/semantic/jsonl message) re-executes AppMainSurfaceGlobalEditorShellTileTree → every TileLeaf / AgentTerminalLeaf / TerminalLeaf / PaneHeader (none memo), including hidden tiled tabs and the display:none retained tree; PaneHeader receives the entire map (TileLeaf.tsx:795). Only Feed (Feed.tsx:294, memo) bails. Live capture: the two renderers burn 55–75% of a core against main's 13–35%; renderer long tasks p99 7.4 s.

Three effects also run over ALL sessions on every replacement: useFeedDebugPersist (paced by #750), usePickerSanity (hook/invalidation/effects.ts:126-138), the codex transcript observation outbox (lifecycle/codexTranscriptObservationOutbox.ts:184-236); getRuntime returns a new identity per call (helpers.ts:87-92).

Expected

  • Panes subscribe to state.workspaceRuntimes[sessionId] with useShallow (the pattern already used in DispatchAgentList.tsx:298-305); memo on TileTree, TileLeaf, AgentTerminalLeaf, TerminalLeaf, PaneHeader; narrow PaneHeader's selector; split the workspace context into stable actions and state slices.
  • The three all-session effects move to per-session subscriptions or a 1 s timer.
  • Migrate consumer by consumer (~25 consumers rely on the fresh object today).

Impact

Re-renders per frame N panes → 1; estimated renderer CPU −30–50% in multi-pane workspaces. Prerequisite for the screen-interest work to pay off fully.
Refs #103, #390. Source: architecture audit 2026-09-03 (scratchpad/arch-perf-audit.md).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions