Chargement Différé
Lazy Load Components (Standalone)
Section intitulée « Lazy Load Components (Standalone) »import { Routes } from '@angular/router';
export const routes: Routes = [ { path: '', loadComponent: () => import('./home/home.component') .then(m => m.HomeComponent) }, { path: 'about', loadComponent: () => import('./about/about.component') .then(m => m.AboutComponent) }, { path: 'users/:id', loadComponent: () => import('./user-detail/user-detail.component') .then(m => m.UserDetailComponent) }];Lazy Load Routes
Section intitulée « Lazy Load Routes »// Main routesexport const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'admin', loadChildren: () => import('./admin/admin.routes') .then(m => m.ADMIN_ROUTES) }, { path: 'shop', loadChildren: () => import('./shop/shop.routes') .then(m => m.SHOP_ROUTES) }];
// admin/admin.routes.tsimport { Routes } from '@angular/router';
export const ADMIN_ROUTES: Routes = [ { path: '', loadComponent: () => import('./admin-dashboard.component') .then(m => m.AdminDashboardComponent) }, { path: 'users', loadComponent: () => import('./admin-users.component') .then(m => m.AdminUsersComponent) }];Stratégies de Préchargement
Section intitulée « Stratégies de Préchargement »Pas de Préchargement (Par défaut)
Section intitulée « Pas de Préchargement (Par défaut) »import { provideRouter } from '@angular/router';
bootstrapApplication(AppComponent, { providers: [ provideRouter(routes) // No preloading ]});PreloadAllModules
Section intitulée « PreloadAllModules »import { provideRouter, withPreloading, PreloadAllModules } from '@angular/router';
bootstrapApplication(AppComponent, { providers: [ provideRouter( routes, withPreloading(PreloadAllModules) // Preload all lazy routes ) ]});Stratégie de Préchargement Personnalisée
Section intitulée « Stratégie de Préchargement Personnalisée »import { Injectable } from '@angular/core';import { PreloadingStrategy, Route } from '@angular/router';import { Observable, of, timer } from 'rxjs';import { mergeMap } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })export class CustomPreloadStrategy implements PreloadingStrategy { preload(route: Route, load: () => Observable<any>): Observable<any> { // Preload if route has data.preload = true if (route.data?.['preload']) { console.log('Preloading:', route.path); return load(); } return of(null); }}
// Usageexport const routes: Routes = [ { path: 'admin', loadChildren: () => import('./admin/admin.routes'), data: { preload: true } // Will preload }, { path: 'shop', loadChildren: () => import('./shop/shop.routes') // Won't preload }];
bootstrapApplication(AppComponent, { providers: [ provideRouter( routes, withPreloading(CustomPreloadStrategy) ) ]});Chargement Différé avec Guards
Section intitulée « Chargement Différé avec Guards »export const routes: Routes = [ { path: 'admin', canActivate: [authGuard], loadChildren: () => import('./admin/admin.routes') .then(m => m.ADMIN_ROUTES) }];Analyse des Bundles
Section intitulée « Analyse des Bundles »# Build and analyze bundlesng build --stats-jsonnpx webpack-bundle-analyzer dist/your-app/stats.jsonChunks Nommés
Section intitulée « Chunks Nommés »// Webpack will create named chunks{ path: 'admin', loadChildren: () => import( /* webpackChunkName: "admin" */ './admin/admin.routes' ).then(m => m.ADMIN_ROUTES)}Chargement Différé des Services
Section intitulée « Chargement Différé des Services »// Service only loaded with lazy route@Injectable()export class AdminService { // ...}
// Fournir dans la route lazyexport const ADMIN_ROUTES: Routes = [ { path: '', component: AdminComponent, providers: [AdminService] // Only loaded with this route }];Tests Chargement Différé
Section intitulée « Tests Chargement Différé »describe('Lazy Loading', () => { it('should lazy load admin module', async () => { const router = TestBed.inject(Router); const fixture = TestBed.createComponent(AppComponent);
await router.navigate(['/admin']); fixture.detectChanges();
const compiled = fixture.nativeElement; expect(compiled.querySelector('app-admin')).toBeTruthy(); });});Bonnes Pratiques
Section intitulée « Bonnes Pratiques »- Charger en différé les routes de fonctionnalités (pas les fonctionnalités principales)
- Utiliser
PreloadAllModulespour une meilleure UX sur les connexions rapides - Créer des stratégies personnalisées pour le préchargement conditionnel
- Charger en différé les routes admin/dashboard
- Garder les fonctionnalités principales chargées immédiatement
- Utiliser l’analyse des bundles pour optimiser
- Précharger en fonction du comportement utilisateur ou de la priorité des routes
- Regrouper les composants liés dans des modules de routes
- Tester les routes lazy pour s’assurer qu’elles fonctionnent
Conseils de Performance
Section intitulée « Conseils de Performance »// ✅ Good: Separate features{ path: 'admin', loadChildren: () => import('./admin/admin.routes')}
// ❌ Bad: Too granular{ path: 'user', loadComponent: () => import('./user.component') // Too small}
// ✅ Good: Group related components{ path: 'dashboard', loadChildren: () => import('./dashboard/dashboard.routes') // dashboard.routes contains multiple related components}Surveiller les Performances de Chargement
Section intitulée « Surveiller les Performances de Chargement »@Injectable({ providedIn: 'root' })export class LoadTimePreloadStrategy implements PreloadingStrategy { preload(route: Route, load: () => Observable<any>): Observable<any> { if (route.data?.['preload']) { const start = performance.now();
return load().pipe( tap(() => { const end = performance.now(); console.log(`Loaded ${route.path} in ${end - start}ms`); }) ); } return of(null); }}
