perf(desktop): code-split the four drawable panels via React.lazy#3116
perf(desktop): code-split the four drawable panels via React.lazy#3116HUQIANTAO wants to merge 1 commit into
Conversation
Memory, History, Settings, and the Update banner are all opened via
state toggles and are mutually exclusive in practice. They each pull
in their own transitive deps (e.g. the history drawer imports the
session-row subcomponent; the settings panel imports the dict-derived
section components; the memory panel imports the remember/saveDoc
actions). On a cold start with a brand-new model the chat was paying
for all four at first paint.
Convert each import to React.lazy() with a Suspense boundary. Each
panel's JS chunk is fetched on first render (the first time the user
clicks the corresponding topbar chip), so the initial bundle loses
those four trees and any of their imports.
The fallback is null because the panels themselves are modal drawers
with their own loading state; a Suspense spinner would be a second
spinner stacked on top of whatever the panel renders.
The .then(m => ({ default: m.X })) adapter handles modules whose
named export is the public surface (every component file in this
repo, per CodeViewer's 'editor seam' pattern).
437626a to
ab87754
Compare
|
Nice perf win — code-splitting these panels is worth doing. Could you rebase on the latest |
|
Covering the whole series (#3116, #3120, #3125, #3126, #3127, #2948) in one note: all six branches now conflict with main-v2 after today's merge batch. They're each still wanted — the React.lazy code-split and the batch delete in particular. If you rebase them onto the latest main-v2 I'll approve fork CI and review as they come green. If any of them no longer applies after the recent status-bar/overview redesign (#3922 reworked that area — the per-turn usage pill in #3127 likely needs rethinking against the new grouped metrics), feel free to close those and keep the rest. |
Memory, History, Settings, and the Update banner are opened via state toggles and are mutually exclusive in practice. They each pull in their own transitive deps. Convert each import to
React.lazy()with a Suspense boundary. Each panel's JS chunk is fetched on first render (the first time the user clicks the corresponding topbar chip), so the initial bundle loses those four trees and any of their imports.The fallback is null because the panels themselves are modal drawers with their own loading state. The
.then(m => ({ default: m.X }))adapter handles modules whose named export is the public surface (per CodeViewer's 'editor seam' pattern).