Cours Angular · Module 12: Sécurité et performances
Optimisation des performances
Dans cette leçon4
La détection des changements OnPush
OnPush, c'est comme des gardes qui ne vérifient que lorsque quelqu'un frappe à la porte :
1@Component({
2 selector: 'app-samurai-card',
3 changeDetection: ChangeDetectionStrategy.OnPush,
4 template: `
5 <div class="card">
6 <h3>{{ samurai().name }}</h3>
7 <p>Clan: {{ samurai().clan }}</p>
8 </div>
9 `
10})
11export class SamuraiCardComponent {
12 // Le composant se met à jour UNIQUEMENT quand :
13 // 1. le signal samurai() change de référence
14 // 2. un événement (clic, saisie) est déclenché
15 // 3. le pipe async reçoit une nouvelle valeur
16 // 4. on appelle manuellement cdr.markForCheck()
17
18 samurai = input.required<Samurai>();
19}Lazy loading de composants avec @defer
1<!-- Chargement quand l'élément entre dans le viewport -->
2@defer (on viewport) {
3 <app-heavy-chart [data]="chartData()" />
4} @placeholder {
5 <div class="chart-placeholder">Chart will load when you scroll down...</div>
6} @loading (minimum 500ms) {
7 <app-spinner />
8} @error {
9 <p>Error loading chart</p>
10}
11
12<!-- Chargement après interaction -->
13@defer (on interaction) {
14 <app-advanced-editor />
15} @placeholder {
16 <button>Click to load editor</button>
17}
18
19<!-- Chargement après un délai -->
20@defer (on timer(2000)) {
21 <app-recommendations />
22} @placeholder {
23 <p>Loading recommendations...</p>
24}
25
26<!-- Chargement conditionnel -->
27@defer (when isAdmin()) {
28 <app-admin-panel />
29}Virtual Scrolling
Pour les listes longues :
1import { ScrollingModule, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
2
3@Component({
4 imports: [ScrollingModule],
5 template: `
6 <cdk-virtual-scroll-viewport itemSize="50" class="viewport">
7 <div *cdkVirtualFor="let samurai of samuraiList()" class="item">
8 {{ samurai.name }}
9 </div>
10 </cdk-virtual-scroll-viewport>
11 `,
12 styles: [`
13 .viewport {
14 height: 400px;
15 }
16 .item {
17 height: 50px;
18 }
19 `]
20})
21export class VirtualListComponent {
22 samuraiList = signal<Samurai[]>([]); // Même avec 10 000 éléments !
23}NgOptimizedImage
1import { NgOptimizedImage } from '@angular/common';
2
3@Component({
4 imports: [NgOptimizedImage],
5 template: `
6 <!-- Lazy loading automatique, srcset, preconnect -->
7 <img
8 ngSrc="/images/samurai.jpg"
9 width="800"
10 height="600"
11 priority
12 placeholder="/images/samurai-placeholder.jpg"
13 >
14
15 <!-- Mode fill pour les images responsives -->
16 <div class="image-container">
17 <img ngSrc="/images/background.jpg" fill>
18 </div>
19 `,
20 styles: [`
21 .image-container {
22 position: relative;
23 width: 100%;
24 height: 300px;
25 }
26 `]
27})
28export class OptimizedImageComponent {}Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Quand un composant avec ChangeDetectionStrategy.OnPush se met-il à jour ?
2. Que fait @defer (on viewport) dans Angular 17+ ?
Voici 2 des 3 questions de cette leçon. Réponds aux autres dans le jeu.
Tâches pratiques dans le jeu
- Éditeur de code
Complète le composant avec l'optimisation OnPush.
- Tri vertical
Ordonne les lignes d'un bloc @defer qui charge un graphique en lazy loading (de haut en bas) :
- Tri horizontal
Ordonne la balise image avec NgOptimizedImage dans le bon ordre (depuis la gauche) :
- Clique dans l'ordre
Clique dans l'ordre pour construire la balise d'ouverture d'un viewport de défilement virtuel :