perf(chat): make session switching feel instant
Switching sessions ran as one synchronous commit: sidebar highlight, URL, a full timeline remount with markdown re-parse, and around nine requests, so nothing changed on screen for 150-250ms after the click. - ChatContainer swaps the timeline on a deferred copy of the selection, so the active row, URL, and tab commit first and the timeline renders behind them; selection policy keeps reading the live store value. - The message fetch starts before the selection is published. - Sidebar rows stop re-rendering on a project switch: directory-scoped sync hooks read the runtime context and a subscribable current-directory source instead of the directory-bearing context; the grouping builder reads git branches through a ref and section caches key the branches they use; descendant ids are keyed by content. Rows per switch went from 73 to 8. - Markdown skips the async re-render when the settled cached blocks are already painted, and mounts synchronously once its lazy module is loaded; the module is preloaded at boot. - A timeline reveal gate holds a freshly opened session at opacity 0 while any provisional markdown paint catches up (250ms cap), then fades the whole timeline in once, so text, tools, and recap appear together. - Switch fan-out trimmed: knowledge summary deduped, MCP status refreshed only when stale, non-repo directories cached by the git repo check, OpenChamber defaults cached briefly, agent memory reused for the same project, goal text cached, PWA manifest rebuilt after the switch settles. - Header tabs snap into the active state and keep the title at the same height in both states. - Prefetch on row press; composer focus moved off the commit. `bun run profile:switch` records ack/content latency, longest task, and requests per switch, cold and warm, and compares runs against a baseline. Measured warm switch: ack 228ms to about 40-60ms, content 228ms to about 100-120ms.
This commit is contained in:
@@ -210,7 +210,7 @@ command, how to stand up a production build to measure against, how to read the
|
||||
artifacts, and the validity guarantees these scripts enforce. Read it before
|
||||
measuring.
|
||||
|
||||
Four unattended capture commands exist; prefer them over ad-hoc timing code,
|
||||
Five unattended capture commands exist; prefer them over ad-hoc timing code,
|
||||
and extend them when a scenario is missing rather than measuring by hand.
|
||||
|
||||
| Command | Answers |
|
||||
@@ -218,6 +218,8 @@ and extend them when a scenario is missing rather than measuring by hand.
|
||||
| `bun run profile:idle` | What the app does while nobody interacts with it. Supports `--session`, `--tab`, `--then-tab`, `--panel`, `--expand-projects` to reach a specific mounted state, plus `--baseline` and `--budget-*` for regression gating. |
|
||||
| `bun run profile:session` | What a streaming assistant response costs. Creates a session, dispatches a prompt through the `openchamber session` CLI, and records until the session reports idle. Reports the long-task distribution, a timeline-trace breakdown, running animations, and output-normalised metrics. |
|
||||
| `bun run profile:animation` | What a CSS animation costs, isolated from the app. Animate only `transform` and `opacity`; everything else recalculates style every frame. |
|
||||
| `bun run profile:switch` | How long switching sessions from the sidebar takes: `ack` (the clicked row highlights) and `content` (the target session's messages are on screen), cold and warm, plus the requests each switch fires. Use it as the regression gate for any change in the sidebar, header, chat container, or markdown first paint. |
|
||||
| `bun run profile:switch` | How long switching sessions from the sidebar takes: `ack` (the clicked row highlights) and `content` (the target session's messages are on screen), cold and warm, plus the requests each switch fires. Use it as the regression gate for any change in the sidebar, header, chat container, or markdown first paint. |
|
||||
| `bun run profile:browser` | A manually driven capture when the interaction cannot be scripted. |
|
||||
|
||||
Both automated commands fail loudly rather than reporting a clean result when
|
||||
|
||||
Reference in New Issue
Block a user