- Ran ANALYZE=true npm run build; copied stats.html to .planning/perf/phase11-baseline.html - Added phase11-baseline-summary.md: chunk sizes, route lazy-load audit, responsive/modal/typography/dead-code findings for plans 11-02..11-06 - Main bundle: 264.63 kB raw / 89.34 kB gzip; 5 user routes still synchronous - Admin/auth routes already lazy-loaded; CSS 98.74 kB raw (expected for full UI)
8.7 KiB
Phase 11 Bundle Baseline
Captured: 2026-06-16 Vite version: 6.4.3 Node environment: production
Command
cd frontend && ANALYZE=true npm run build
Output artifact: frontend/stats.html — copied to .planning/perf/phase11-baseline.html.
Bundle Sizes (pre-optimization)
| Chunk | Raw | Gzip |
|---|---|---|
index-BGwBmeoY.js (main bundle) |
264.63 kB | 89.34 kB |
index-BtLvezBC.css (Tailwind CSS) |
98.74 kB | 17.12 kB |
AdminAiView-DsyOjb0b.js |
14.99 kB | 4.68 kB |
AdminUsersView-DFHwCZvr.js |
12.29 kB | 3.76 kB |
AdminAuditView-COYge5oc.js |
9.71 kB | 2.98 kB |
AdminQuotasView-Bjrfs1gN.js |
4.60 kB | 1.88 kB |
LoginView-CM2pkdzs.js |
6.81 kB | 1.90 kB |
RegisterView-B2PzAwRW.js |
3.76 kB | 1.34 kB |
AdminLayout-DTKBjMfr.js |
2.71 kB | 1.10 kB |
AdminOverviewView-GYxFAo8h.js |
3.56 kB | 1.19 kB |
AdminLayout-TsYHjENN.css |
0.75 kB | 0.35 kB |
PasswordResetView-BSR1dx14.js |
2.32 kB | 1.13 kB |
SharedView-DTW18Ruc.js |
2.14 kB | 1.14 kB |
admin-D1I3smx6.js |
2.24 kB | 0.91 kB |
NewPasswordView-mjRpmRNW.js |
2.13 kB | 1.11 kB |
Total JS (raw): ~343 kB
Total JS (gzip): ~114 kB
Key Observations
Main bundle (264.63 kB raw / 89.34 kB gzip)
The main bundle is large because 5 user-facing routes are still imported synchronously at the top of router/index.js:
FileManagerView— intentionally synchronous (critical first authenticated surface, per D-10)TopicsView— synchronous, should be lazy-loadedDocumentView— synchronous, should be lazy-loadedSettingsView— synchronous, should be lazy-loadedCloudStorageView— synchronous, should be lazy-loadedCloudFolderView— synchronous, should be lazy-loaded
Plan 11-02 will lazy-load all 5 of the above (keeping FileManagerView synchronous).
Already lazy-loaded (good)
- All auth views:
LoginView,RegisterView,PasswordResetView,NewPasswordView— each in its own chunk - All admin views:
AdminOverviewView,AdminUsersView,AdminQuotasView,AdminAiView,AdminAuditView— each in its own chunk AdminLayout— own chunkSharedView— own chunk
Vite warning: auth.js mixed import
Vite warns that auth.js is both dynamically imported (from api/utils.js) and statically imported by many components. This means auth.js stays in the main bundle even when lazy-loading routes. This is expected behavior — auth.js must be available synchronously for the navigation guard on every page load.
CSS
The Tailwind purged CSS at 98.74 kB raw / 17.12 kB gzip is expected for a full admin + user interface. The safelist with dynamic color patterns adds some bulk but is necessary for runtime-generated topic badge colors. No action needed here.
Routes Audit (lazy vs. synchronous)
| Route path | Component | Pre-11-02 status |
|---|---|---|
/ |
FileManagerView | synchronous (intentional — D-10) |
/topics |
TopicsView | synchronous → lazy in 11-02 |
/topics/:name |
TopicsView | synchronous → lazy in 11-02 |
/document/:id |
DocumentView | synchronous → lazy in 11-02 |
/settings |
SettingsView | synchronous → lazy in 11-02 |
/folders/:folderId |
FileManagerView | synchronous (reuses main bundle component) |
/cloud |
CloudStorageView | synchronous → lazy in 11-02 |
/cloud/:provider/:folderId(.*) |
CloudFolderView | synchronous → lazy in 11-02 |
/login |
LoginView | already lazy |
/register |
RegisterView | already lazy |
/password-reset |
PasswordResetView | already lazy |
/password-reset/confirm |
NewPasswordView | already lazy |
/shared |
SharedView | already lazy |
/admin (layout) |
AdminLayout | already lazy |
/admin (all children) |
AdminOverviewView, etc. | already lazy |
Expected main bundle reduction after 11-02: ~30–60 kB raw (splitting out Topics, Document, Settings, Cloud views).
Responsive / Visual Audit Findings
Synchronous non-critical route imports (Plan 11-02)
All 5 identified in route table above.
Responsive sidebar/admin sidebar gaps (Plan 11-03)
App.vue: desktop-onlyflex h-screen overflow-hiddenshell;AppSidebaris always visible (no mobile handling).AdminLayout.vue: identical desktop-only pattern;AdminSidebaralways visible.- No hamburger button, no drawer, no mobile nav exists anywhere.
- Required: hamburger button + slide-in overlay drawer with
<Teleport to="body">backdrop. - State location: layout-local
ref()inApp.vueandAdminLayout.vue(route-change watcher closes drawer) — not a shared Pinia store (per D-05, R-15 research verdict).
Tables / grids that overflow below sm/md (Plan 11-03)
StorageBrowser.vueheader row and all data rows:grid-cols-[2rem_1fr_6rem_8rem_6rem]— fixed 5-column grid.- The "Size" column header has
hidden md:block, data cells havehidden md:block— correct. - The "Modified" column header has
hidden sm:block, data cells havehidden sm:block— correct. - But the
grid-colstemplate is still5-columneven when the last 2 columns are hidden — this leaves empty grid tracks on mobile. The grid template needs to be responsive:grid-cols-[2rem_1fr_auto]on small,grid-cols-[2rem_1fr_6rem_auto]on md,grid-cols-[2rem_1fr_6rem_8rem_6rem]on sm/lg. - Row action buttons:
p-1.5onw-3.5 h-3.5icons → button is ~26px at most. Below md, touch targets needmin-h-[36px] min-w-[36px].
Modal overflow below 640px (Plan 11-04)
ShareModal.vue: nomax-horoverflow-y-auto; panel usesmax-w-md w-full mx-4. Will overflow on very short phones.CloudCredentialModal.vue: nomax-horoverflow-y-auto; Nextcloud form with advanced section can be tall; panel usesmax-w-md p-6. Overflow risk is concrete.FolderDeleteModal.vue: smaller content, less risk, but should get the standard safe pattern for consistency.DocumentPreviewModal.vue: full-screen overlay (fixed inset-0). Structurally correct for full-screen; preserves full-screen behavior. Header usespx-6 py-3; no overflow risk. No action needed except verifying narrow-screen header doesn't clip.
Inconsistent focus states (Plan 11-05)
- Current pattern:
focus:ring-2 focus:ring-indigo-500used throughout, butfocus-visible:is rarely used. - Should normalize to
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-1per research convention. - Mouse clicks will no longer show focus rings (correct a11y behavior); keyboard navigation will still show them.
Inconsistent form patterns (Plan 11-04)
@tailwindcss/formsis active and normalizes browser defaults. Many inputs still carry redundantborder border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500— partially redundant with forms plugin. Plan 11-04 should normalize these.- Some inputs lack
focus-visible:(usefocus:instead) — part of focus normalization.
Inconsistent spacing/typography (Plan 11-05)
- Skeleton widths:
AppSidebar.vueuses:style="{ width: (50 + n * 15) + 'px' }"for decorative skeleton widths — can be converted tow-20,w-24,w-28static Tailwind classes. - Typography conventions found in codebase (to be normalized):
- Page titles: mostly
text-2xl font-semibold— consistent. - Section titles:
text-lg font-semibold/font-semibold text-gray-800/font-semibold text-gray-900— the color drifts; normalize totext-lg font-semibold text-gray-900. - Labels:
text-sm font-semibold text-gray-700/text-sm font-semibold text-gray-900— normalize totext-sm font-semibold text-gray-700. - Body text:
text-sm text-gray-600— mostly consistent. - Captions/metadata:
text-xs text-gray-400— mostly consistent.
- Page titles: mostly
- Border radius:
rounded-xlvsrounded-2xlon modal panels —ShareModalandFolderDeleteModaluserounded-2xl;CloudCredentialModalusesrounded-xl. Normalize torounded-xl.
Unreferenced files and imports (Plan 11-06)
AccountView.vue: exists atsrc/views/AccountView.vue. The router has{ path: '/account', redirect: '/settings' }but does NOT import or renderAccountView. It is completely unreferenced. SAFE TO DELETE in Plan 11-06 (verify no other reference before deleting).HomeView.vueandFolderView.vue: confirmed absent (per AGENTS.md requirement). No action.- Admin test files
AdminAiConfigTab.test.js,AdminQuotasTab.test.js,AdminUsersTab.test.js— may reference deleted components (old tab-based admin). Classify in Plan 11-06. - Unused imports: a scan during Plan 11-06 pass will catch per-file orphans.
Deviation from 11-RESEARCH.md
None. All research findings confirmed by live code review and build output.