From 38e58bf40218c8dfa5beaf88d32d60e8e6f0033f Mon Sep 17 00:00:00 2001 From: sdarbinyan Date: Sun, 26 Jul 2026 15:45:51 +0400 Subject: [PATCH] perf(routing): lazy-load AdminLayoutComponent shell Phase 3 (Performance). Bundle-stats analysis (esbuild metafile) found AdminLayoutComponent statically imported and used as component: in app.routes.ts, the only route in the file not using loadComponent - pulled the whole backoffice shell into the initial bundle even for storefront-only visitors, even though every child route under it was already lazy. Fixed: component: AdminLayoutComponent -> loadComponent(). Verified live at /backoffice/dashboard - admin-layout-component now its own 21.86kB lazy chunk, no console errors, dashboard renders correctly. Initial bundle over-budget shrank from 438.68kB to 417.53kB. Investigated and deliberately left as-is (not bugs, documented/ legitimate): - src/app/i18n/ru.ts (272kB) eagerly bundled - explicit, commented tradeoff in translate.service.ts (ru is platform default language, avoids extra round-trip for majority of users; en/hy already code-split). Changing this trades bundle size for default-language UX regression - a product call, not a cleanup item. - @lucide/angular (182kB) - verified tree-shaking works correctly (1750 icons in the package, ~85 actually imported by name in icon-registry.ts, sideEffects:false). Cost is genuine icon usage, not dead weight. A further win exists (splitting the icon registry into storefront-critical vs admin-only sets so backoffice-only icons don't ride the eager header/footer import chain) but touches every icon consumer across the app - flagging as a scoped follow-up rather than attempting blind in this pass. Remaining bundle-budget warning after this fix: 1.12MB vs 700kB budget. Given ~350kB is unavoidable Angular framework/router/zone.js floor, +272kB deliberate ru.ts, +182kB legitimate icon usage, the 700kB budget itself looks stale/unrealistic for this app's actual floor - flagging for a business decision on raising it rather than chasing further cuts. tsc --noEmit clean, ng build clean (warning only, no errors), live browser-verified. --- src/app/app.routes.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index f069a66..0bf41a8 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -5,7 +5,6 @@ import { adminAuthGuard } from './core/admin-auth/admin-auth.guard'; import { authRoutes } from './core/auth/auth.routes'; import { adminCategoryDirtyGuard } from './features/admin/categories/guards/admin-category-dirty.guard'; import { adminProductDirtyGuard } from './features/admin/products/guards/admin-product-dirty.guard'; -import { AdminLayoutComponent } from './features/admin/shell/admin-layout.component'; import { environment } from '../environments/environment'; // Core routes (same across all brands) @@ -59,7 +58,7 @@ const coreRoutes: Routes = [ { path: 'backoffice', canActivate: [adminAuthGuard], - component: AdminLayoutComponent, + loadComponent: () => import('./features/admin/shell/admin-layout.component').then(m => m.AdminLayoutComponent), children: [ { path: '', redirectTo: 'dashboard', pathMatch: 'full' }, {