Conversation
There was a problem hiding this comment.
🔵 Needs a closer look
The change affects bundle size and route-loading behavior and requires human verification of production performance.
Pull request overview
Updates route loading to eagerly load five frequently used screens, improving first-navigation responsiveness while retaining lazy loading for other routes.
Changes:
- Static-imports Credentials, Hosts, Inventory, Projects, and Templates.
- Keeps less-used routes lazy-loaded.
File summaries
| File | Description |
|---|---|
ascender/ui/src/routeConfig.tsx |
Adjusts route screen imports between static and lazy loading. |
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Sorry about the sluggishness, that lazy split in #939 was mine. I built all three locally on node 24 so this is measured rather than guessed. Your numbers reproduce exactly:
One correction on the mechanismThe built <script type="module" crossorigin src="/static/js/index.je_MZB9K.js">
<link rel="modulepreload" crossorigin href="/static/js/ContentError.XQ--JhbY.js">So production is not preloading the lazy routes today. Vite's The preload hints you are describing actually appear because of this PR: the count goes from 1 to 24, since the five screens become static imports of the entry. Your conclusion still holds, just for a different reason. Dev is slow because Vite transforms modules on demand with no bundling. Production is one round trip for a prebuilt chunk, and those chunks are small:
So production will still cost a fetch on first click, but tens of milliseconds rather than a second. A cheaper way to get the same resultWarm those five during idle once the authenticated shell has painted, instead of putting them in the entry: const POPULAR_SCREENS = [
() => import('screens/Template'),
() => import('screens/Inventory'),
() => import('screens/Host'),
() => import('screens/Project'),
() => import('screens/Credential'),
];Called from
I built it:
The 180 bytes is the prefetch function itself. Splitting is preserved, and the five screens stay their own chunks. It also fixes the thing you actually hit: in dev the transform happens during idle rather than on the click, so Devel stops feeling sluggish too. Worth adding:
The honest trade-off: prefetch spends bandwidth on screens a session may never open, roughly 100 KB gzipped for the five, at idle and after paint. That is the one axis where a static import is not worse, since it spends the same bytes anyway, just earlier and for everyone. What I measured is build cost: entry size, chunk count, clean typecheck, green Sent it as #1032 so you can compare the two side by side. |
ctrliq#939 split every screen out of the entry bundle, which is why the first click to a page now waits on a fetch. ctrliq#1017 answers that by putting the five most used screens back into the entry, at 108 KB to 316 KB gzipped. The registry does the same job for less. import() during idle populates the module registry, so when the route renders React.lazy resolves from it with no fetch and no Suspense fallback. Same user visible result as a static import, without those screens entering the bundle everyone downloads before the login form. Measured: the entry grows 197 bytes rather than 208 KB, and all 118 chunks stay split. It also helps the environment the slowness was reported in. Dev is slow because Vite transforms on demand, and this moves that transform into idle time rather than the click. Called from RenderAppContainer, so nothing is warmed on the login page, with a requestIdleCallback timeout so a busy tab still gets it, and skipped on saveData or a 2g connection.
In a previous PR, we modified all routes to use
React.lazy()which helped reduce the rather large initial download size. This is a good thing, but (at least in Devel) it is affecting the user experience as every 1st click to a page now takes ~1 additional second and makes it feel sluggish. I believe this to only be affecting Dev, as a production build resolves each lazy route to one prebuilt chunk with module preload hints, so the delay there is a single small round trip. So I am leaving this as a draft until I can verify in a production environment (awaiting operator updates).All this PR does is take the main 5 pages and adds them back as static imports, so those pages will always load faster.
It added ~200kb to the entry chunk.