Cours Angular · Module 12: Sécurité et performances

Optimisation des performances

2 min de lecture
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. 1. Quand un composant avec ChangeDetectionStrategy.OnPush se met-il à jour ?

  2. 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 :

Articles utiles