--- phase: 11-visual-design-responsive-layout-cleanup plan: 2 subsystem: frontend/router tags: [perf, lazy-load, routing, bundle-split, PERF-03] dependency_graph: requires: [11-01] provides: [perf03-lazy-routes] affects: [frontend/src/router/index.js, frontend/src/router/__tests__/router.guard.test.js] tech_stack: added: [] patterns: [dynamic import via () => import() for non-critical route components] key_files: created: [] modified: - frontend/src/router/index.js - frontend/src/router/__tests__/router.guard.test.js decisions: - "FileManagerView stays synchronous for / per D-10 — critical first authenticated surface; lazy-loading would delay initial paint for the most common entry point" - "/folders/:folderId reuses the synchronous FileManagerView so no new chunk is created for folder navigation" - "All other authenticated user routes (Topics, Document, Settings, Cloud, CloudFolder) are now lazy-loaded via () => import()" - "Admin child routes and auth routes were already lazy-loaded and remain unchanged" metrics: duration_minutes: 2 tasks_completed: 6 files_created: 0 files_modified: 2 completed_date: "2026-06-16" --- # Phase 11 Plan 2: Lazy-Load Non-Critical Routes Summary Lazy-loaded 5 non-critical authenticated route components, reducing the main JS bundle from 264.63 kB to 180.17 kB and emitting 5 separate route chunks, satisfying PERF-03. ## What Was Built ### Tasks 1-4 — Router lazy-loading `frontend/src/router/index.js` updated: - **Removed** static `import` statements for `TopicsView`, `DocumentView`, `SettingsView`, `CloudStorageView`, `CloudFolderView`. - **Replaced** each with an inline `() => import('../views/...View.vue')` dynamic import on the route's `component` field. - **Kept** `FileManagerView` as the sole static synchronous import (decision D-10). A comment block in `router/index.js` documents the rationale. - **Kept** `/folders/:folderId` using the synchronous `FileManagerView` component — no new chunk needed since the component is already in the initial bundle. - **Preserved** all existing lazy imports for admin children, auth views, `SharedView`, and `AdminLayout`. Acceptance criterion confirmed: `grep "import .*View" frontend/src/router/index.js` returns only `FileManagerView`. ### Task 5 — Extended router guard tests `frontend/src/router/__tests__/router.guard.test.js` extended with 15 new tests across 2 new describe blocks: - `router — admin guard` extended with: non-admin blocked from `/admin/users` and `/admin/quotas` (child route inheritance via `to.matched.some()`), admin redirected away from `/settings` and `/cloud` (D-09) - `router — refresh-before-guard` (new): verifies `refresh()` is called when `accessToken` is null, redirect to `/login` when refresh fails, no refresh call for public routes - `router — lazy-loaded routes resolve` (new): verifies all 5 newly-lazy routes (`/topics`, `/topics/:name`, `/document/:id`, `/settings`, `/cloud`, `/cloud/:provider/:folderId`) navigate correctly for authenticated regular users; `/folders/:folderId` and `/shared` also covered All 234 tests pass (up from 219 in Plan 11-01). ### Task 6 — Build verification `npm run build` succeeds; route chunks emitted: | Chunk | Size | |-------|------| | `CloudFolderView-*.js` | 1.99 kB | | `CloudStorageView-*.js` | 2.32 kB | | `DocumentView-*.js` | 9.17 kB | | `TopicsView-*.js` | 10.98 kB | | `SettingsView-*.js` | 60.72 kB | | Main bundle (`index-*.js`) | 180.17 kB (was 264.63 kB) | Main bundle reduction: **84.46 kB raw** (~32%). ## Verification - `rg "import .*View" frontend/src/router/index.js` returns only `FileManagerView` — confirmed - Admin child routes remain lazy-loaded — confirmed - `npm test`: 234 tests pass, 30 test files - `npm run build`: succeeds, split route chunks emitted ## Deviations from Plan None — plan executed exactly as written. ## Known Stubs None. ## Threat Flags None — this plan makes no network, auth, or schema changes. Guard behavior is unchanged; only the loading strategy for view components was modified. ## Self-Check: PASSED - `frontend/src/router/index.js`: modified, only `FileManagerView` statically imported - `frontend/src/router/__tests__/router.guard.test.js`: modified, 15 new tests - Commit `4fa07b3` exists in git log - Build output shows 5 route chunk files