5.1 KiB
Phase 11 Bundle Final Summary — Baseline vs. Final Comparison
Captured: 2026-06-17 Vite version: 8.0.16 Node environment: production
Command
cd frontend && npm run build
cd frontend && ANALYZE=true npm run build # generates stats.html → .planning/perf/phase11-final.html
Side-by-Side Comparison
| Metric | Baseline (pre-11-02) | Final (post-Phase-11) | Delta |
|---|---|---|---|
| Main entry chunk — raw | 264.63 kB | 30.31 kB | -234.32 kB (-88.5%) |
| Main entry chunk — gzip | 89.34 kB | 9.59 kB | -79.75 kB (-89.3%) |
| CSS main — raw | 98.74 kB | 100.39 kB | +1.65 kB |
| CSS main — gzip | 17.12 kB | 17.83 kB | +0.71 kB |
| JS chunk count | 15 chunks | 37 chunks | +22 chunks |
| Total output files | 15 | 39 | +24 |
Note: The final measurement was refreshed after the Vite 8 security bump that closed the esbuild high-severity audit finding. Vite 8 performs more shared/runtime chunk splitting than the earlier Vite 6 final measurement, so the "main entry chunk" is no longer directly equivalent to the old single large app chunk.
What Changed
Main entry reduction
Plan 11-02 lazy-loaded 5 user routes that were previously synchronous imports. The later Vite 8 security bump also split shared runtime/vendor code into smaller chunks, leaving the main entry chunk at 30.31 kB raw / 9.59 kB gzip.
| New lazy chunk | Size (raw) | Size (gzip) | Route |
|---|---|---|---|
SettingsView-*.js |
60.95 kB | 19.27 kB | /settings |
TopicsView-*.js |
12.46 kB | 4.02 kB | /topics, /topics/:name |
DocumentView-*.js |
10.29 kB | 3.88 kB | /document/:id |
CloudStorageView-*.js |
2.53 kB | 1.32 kB | /cloud |
CloudFolderView-*.js |
2.14 kB | 1.13 kB | /cloud/:provider/:folderId |
AppSpinner-*.js |
0.54 kB | 0.39 kB | (shared sub-chunk for spinner) |
SettingsView contains the TotpEnrollment, PasswordStrengthBar, and cloud-connection components, so keeping it lazy remains the largest route-level win.
CSS slight increase (+1.65 kB raw)
The responsive layout additions in Plans 11-03/11-04/11-05 added new Tailwind utility classes (translate-x-0, -translate-x-full, max-h-[90vh], overflow-y-auto, focus-visible:ring-*, min-h-[36px], min-w-[36px]) that were not in the purged baseline. The modest increase confirms these classes are in active use.
AdminLayout now includes drawer JS
AdminLayout is 4.23 kB raw / 1.72 kB gzip due to the responsive hamburger drawer state added in Plan 11-03. The drawer logic lives in AdminLayout.vue per the D-04/D-05 sidebar-state rule.
Vite 8 security remediation
During milestone audit remediation, npm audit --audit-level=high reported GHSA-gv7w-rqvm-qjhr through the Vite 6 esbuild dependency. Vite was upgraded to ^8.0.16; the current final analyzer artifact and this summary reflect the post-remediation build.
New Lazy Route Chunks (Plan 11-02)
Before Phase 11, 5 user routes were synchronous — they were bundled into the main JS chunk and downloaded by every visitor on first load, even users who never opened Settings or Cloud storage.
After Plan 11-02, each of these routes is a separate chunk loaded only when the user navigates to that route:
- SettingsView — largest win; downloads only when user goes to
/settings - TopicsView — downloads only when navigating to
/topicsor topic detail - DocumentView — downloads only when opening a document detail page
- CloudStorageView — downloads only when user opens cloud storage
- CloudFolderView — downloads only when browsing a cloud provider's folders
Already lazy at baseline: all auth views (LoginView, RegisterView, PasswordResetView, NewPasswordView), all admin views (AdminOverviewView, AdminUsersView, AdminQuotasView, AdminAiView, AdminAuditView), AdminLayout, SharedView.
Kept synchronous intentionally: FileManagerView — this is the critical first authenticated surface rendered at /. Lazy-loading it would delay the initial paint for logged-in users arriving via refresh-token cookie (the most common entry point). Documented in router/index.js per D-10.
Interpretation
A large reduction in the main entry chunk remains after the Vite 8 refresh: the entry is 30.31 kB raw / 9.59 kB gzip, with route and shared code split into on-demand chunks. The exact first-load byte count now depends on the browser's module graph preloading behavior, but the critical path no longer forces Settings, Topics, Document detail, or Cloud views into the initial application entry.
The chunk-splitting strategy is correct: the 6 new chunks are only fetched on demand, adding zero latency to the critical / home path.
Artifacts
| File | Description |
|---|---|
.planning/perf/phase11-baseline.html |
Rollup visualizer HTML before any Phase 11 changes |
.planning/perf/phase11-baseline-summary.md |
Baseline analysis (Plan 11-01) |
.planning/perf/phase11-final.html |
Rollup visualizer HTML after all Phase 11 changes |
.planning/perf/phase11-final-summary.md |
This file |