Optimisez le chargement avec les deferrable views d'Angular 17 : lazy load conditionnel des composants avec @defer, @loading, @error et @placeholder.
Introduction aux deferrable views
Les deferrable views (vues différées) sont l'une des fonctionnalités les plus puissantes d'Angular 17. Elles permettent de charger des parties de l'interface en différé — seulement quand c'est nécessaire — sans avoir à écrire une ligne de code de lazy loading manuel.
Avant Angular 17, pour faire du lazy loading d'un composant, il fallait utiliser les routes avec loadComponent() ou loadChildren(). Désormais, @defer permet de différer le chargement directement dans le template, sans configuration de routes.
@defer charge automatiquement le JavaScript d'un composant en différé. Le composant n'est inclus ni dans le bundle initial ni rendu tant que le trigger n'est pas déclenché.
Syntaxe de base @defer
La syntaxe la plus simple : le composant se charge quand le navigateur est inactif (idle).
@defer {
<heavy-chart-component />
}
Dans cet exemple, HeavyChartComponent sera chargé uniquement quand le navigateur sera disponible, sans bloquer le rendu initial.
Les triggers de déclenchement
Angular 17 propose plusieurs triggers pour contrôler quand le chargement différé se déclenche :
<!-- Déclenche quand l'élément est visible (viewport) -->
@defer (on viewport) {
<comments-section />
}
<!-- Déclenche au survol de la souris -->
@defer (on hover) {
<tooltip-content />
}
<!-- Déclenche au premier clic -->
@defer (on interaction) {
<expandable-panel />
}
<!-- Déclenche après un délai -->
@defer (on timer(2s)) {
<notification-banner />
}
<!-- Déclenche quand le navigateur est inactif (défaut) -->
@defer (on idle) {
<analytics-widget />
}
<!-- Déclenche immédiatement -->
@defer (on immediate) {
<above-fold-content />
}
On peut aussi utiliser un signal ou une expression booléenne avec when :
@defer (when isAuthenticated()) {
<user-dashboard />
}
Les blocs @loading, @error et @placeholder
Trois blocs complémentaires permettent de gérer les états intermédiaires :
@defer (on viewport) {
<heavy-component />
} @loading (minimum 200ms) {
<div class="spinner">Chargement...</div>
} @error {
<div class="alert">Erreur lors du chargement.</div>
} @placeholder (minimum 100ms) {
<div class="skeleton-placeholder"></div>
}
@placeholder— affiché avant que le chargement commence@loading— affiché pendant le chargement@error— affiché si le chargement échoue
minimum évite le flash de contenu en garantissant un temps d'affichage minimal pour @placeholder et @loading.
Le prefetch avec @defer
Le prefetch permet de pré-télécharger le JavaScript d'un composant avant de l'afficher, pour un rendu instantané au moment du trigger :
@defer (on interaction; prefetch on idle) {
<video-player />
} @placeholder {
<button>Lire la vidéo</button>
}
Dans cet exemple, le bundle de VideoPlayer est téléchargé quand le navigateur est inactif, mais le composant ne s'affiche qu'au clic de l'utilisateur.
Cas d'usage pratiques
Voici les scénarios où @defer apporte le plus de valeur :
- Sections "below the fold" — commentaires, recommandations, widgets secondaires
- Composants lourds — éditeurs, graphiques, cartes interactives
- Contenu conditionnel — modales, tooltips, panneaux dépliables
- Amélioration du LCP — réduire le bundle initial pour améliorer les Core Web Vitals
@defer permet des scores Lighthouse proches de 100 sur des applications complexes.