Aller au contenu

Lab 21 : Vues différables (@defer)

step-18-album-wholesale-v21-post-signal-form

Dans ce lab, vous utiliserez le bloc @defer d’Angular pour charger des composants lourds uniquement lorsqu’ils sont réellement nécessaires. Vous explorerez les différents types de déclencheurs et observerez l’impact réseau dans les DevTools du navigateur.

Trouvez un composant dans l’application qui est rendu sous la ligne de flottaison et qui est relativement coûteux à afficher (ex. : AlbumDetailComponent, un graphique, ou CartSummaryComponent).

Remplacez la référence directe dans le template par un bloc @defer :

<!-- Avant -->
<app-album-detail [album]="selected" />
<!-- Après -->
@defer {
<app-album-detail [album]="selected" />
} @loading {
<p>Chargement des détails…</p>
} @placeholder {
<div class="placeholder-box">Survolez pour prévisualiser</div>
} @error {
<p>Impossible de charger le composant.</p>
}

Testez chaque déclencheur en modifiant la ligne @defer :

<!-- Charger quand le navigateur est inactif -->
@defer (on idle) { ... }
<!-- Charger quand le bloc entre dans le viewport -->
@defer (on viewport) { ... }
<!-- Charger quand l'utilisateur clique sur un bouton -->
<button #loadBtn>Charger les détails</button>
@defer (on interaction(loadBtn)) { ... }
<!-- Charger quand l'utilisateur survole -->
@defer (on hover(loadBtn)) { ... }
<!-- Charger après un délai fixe -->
@defer (on timer(3s)) { ... }
<!-- Charger immédiatement (mais dans un chunk différé) -->
@defer (on immediate) { ... }

Ouvrez l’onglet Réseau du navigateur, filtrez par JS, et vérifiez que le chunk du composant ne se télécharge que lorsqu’il est déclenché.

Préchargez le chunk tôt tout en retardant le rendu :

@defer (on interaction(loadBtn); prefetch on idle) {
<app-album-detail [album]="selected" />
} @placeholder {
<button #loadBtn>Afficher les détails</button>
}

Observez dans l’onglet Réseau : le chunk JS est téléchargé pendant la période d’inactivité, il n’y a donc aucun délai au clic.

Ajoutez un temps d’affichage minimum pour @loading afin d’éviter les scintillements :

@defer (on viewport; prefetch on idle) {
<app-album-detail [album]="selected" />
} @loading (after 200ms; minimum 500ms) {
<p>Chargement…</p>
} @placeholder (minimum 300ms) {
<div class="placeholder-box"></div>
}

Exécutez le build de production et confirmez que le composant est dans un chunk séparé :

Fenêtre de terminal
ng build

Inspectez la sortie dans dist/ — le composant différé devrait apparaître comme un fichier JS séparé.