Skip to content

perf(ui-react): memoize stable session rows - #514

Merged
Astro-Han merged 3 commits into
mainfrom
perf/react-memo-boundaries-pr9
Jul 4, 2026
Merged

Astro-Han merged 3 commits into
mainfrom
perf/react-memo-boundaries-pr9

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Jul 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Memoize the private SessionRow render boundary inside SessionHistoryList.
  • Stabilize the real AppShell -> SessionListPanel sidebar inputs so onSelectSession and rowActions no longer churn on unrelated AppShell renders.
  • Keep the render-count contract on the public SessionHistoryList path with rowActions present, unrelated parent updates, and a single-row streaming update.

Why

Refs #477

PR9 is the evidence-based memo pass after the React cleanup series. SessionRow has local hover/edit/pending state and sits under a sidebar owner that can rerender for unrelated parent state. The first pass memoized the row, but review found the real AppShell owner still passed a fresh select handler and fresh row action object every render, which would defeat the memo boundary on the hot sidebar path. This update makes those owner props stable while still dispatching to the latest action handlers through refs.

Scope

Changed:

  • packages/ui/src/session-history-list.tsx: wrap private SessionRow with React memo.
  • apps/desktop/src/renderer/app-shell.tsx: pass stable sessionListSelectSession and stable sessionRowActions into SessionListPanel.
  • apps/desktop/src/main/__tests__/ui-render-memo-boundary-contract.test.ts: keep only the public SessionHistoryList render-count contract; it no longer source-scans AppShell, regex-injects SessionRow, or mocks @maka/core.
  • apps/desktop/src/main/__tests__/session-row-actions-fail-soft-contract.test.ts: keep owner no-inline and fail-soft row action wiring checks in the existing AppShell wiring contract.

Not included:

  • No visual redesign.
  • No ToolActivity memo boundary without render evidence.
  • No ChatView or AppShell split.
  • No public API changes.

Verification

  • RED: before the AppShell fix, ui-render-memo-boundary-contract failed because sessionListSelectSession / sessionRowActions did not exist and SessionListPanel still received inline props.
  • GREEN: npm run -w @maka/ui build
  • GREEN: npm run -w @maka/desktop build:main && node --test apps/desktop/dist/main/__tests__/ui-render-memo-boundary-contract.test.js apps/desktop/dist/main/__tests__/session-row-actions-fail-soft-contract.test.js (5 passed)
  • GREEN: npm run -w @maka/desktop build:renderer (passes; existing Vite large chunk warning remains)
  • GREEN: npm run -w @maka/desktop test (1864 passed)
  • KNOWN BASELINE FAIL: npm run -w @maka/ui test still fails on the pre-existing chat-primitives.test footer/lineage merge assertions (gap-[6px], gap-[3px]); this PR does not touch those files or classes.

User-facing impact

No behavior or visual change intended. Sidebar session rows should do less React work when parent/sidebar state changes without changing the row props.

Reviewer notes

Review fix commits:

  • 5e8e2028 perf(ui-react): stabilize sidebar row inputs
  • 654bb91d test(ui-react): slim sidebar memo contract

The render-count test still bundles the built UI file so React client rendering can run inside the Node desktop test environment without adding a DOM test dependency, but the temporary bundle now only replaces OverlayScrollbars' browser-only side effect. It uses the real @maka/core formatter and the built packages/ui/dist/session-history-list.js output. Owner no-inline coverage moved to the existing AppShell row-action wiring contract, where re-inlining onSelectSession or rowActions fails the test.

@Astro-Han
Astro-Han merged commit 2f54ad6 into main Jul 4, 2026
@Astro-Han
Astro-Han deleted the perf/react-memo-boundaries-pr9 branch July 4, 2026 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant