L’arrivée de defer, en angular 17, validé en angular 18 est une très belle étape dans l’architecture lazy loadable de nos composants !
Defer permet de lazy loader un composant, qui est enfant d’un autre, donc depuis une simple déclaration sur notre template, un composant devient un composant LL : lazy loadable.
@defer
https://angular.dev/guide/defer#defer
https://blog.angular-university.io/angular-defer
https://angularexperts.io/blog/angular-defer-lazy-loading-total-guide
But: reduction de la taille initiale du bundle !
But : améliorer les Core web vitals. https://developers.google.com/search/docs/appearance/core-web-vitals?hl=fr
Surtout :
- Largest Contentful Paint (LCP) : https://fr.semrush.com/blog/core-web-vitals-lcp/
- Time to First Byte (TTFB) : https://kinsta.com/fr/blog/ttfb/
Point important : si le chargement d’un composant deferré change l’affichage, il fortement recommandé de le présenter sous la ligne de flottaison de l’écran.
On peut différer des composants si
- standalone
- pas référencés dans le même fichier
Exemple simple
app component et child component
Et ce, malgré le fait qu’il est mis en import dans le AppComponent
Second exemple
On a un child one en defer, et dans ce child one on a un child two en defer.
ça génère deux lazy chunk
Troisième exemple
App component > defer child-one > defer child two > contient child three.
Le child 3 est inclut dans le child 2 en lazy component.
Quatrième exemple
On peut mettre plusieurs composant dans un defer
les 2 passent lazy files
cinquième exemple
lazy loading avec un composant qui va faire être en defer
Il va créer deux fichiers en lazy
- un pour les routes + les composants du fichier routes,
- et un autre pour le composant qui est le defer
Comportement
defer se déclenche par défaut quand le navigateur est en idle, via : requestIdleCallback
@placeholder
Vu que le defer ne rend rien par défaut, on peut préparer du contenu en attendant le chargement du composant enfant.
Tout le code appelé ici sera eager, et donc dans le bundle initial.
minimum
On peut ajouter une durée minimum d’affichage du placeholder, pour éviter les effets dérangeants si le contenu du defer se charge trop rapidement.
C’est bien le temps avant chargement du contenu du defer, même s’il a déjà récupéré les composants contenus dans le defer.
@loading
NOTE: Si on a un placeholder avec un minimum et un loading, on ne voit pas le loading, car le placeholder dure plus longtemps que le loading.
Si on met juste un loading, on a bien l’affichage durant le temps de chargement.
minimum
Durée minimum d’affichage du contenu du @loading.
after
on affiche le contenu du loading après ce temps d’attente. Si le chargement met moins de temps, on affiche rien
placeholder vs loading
la partie @placeholder s’affiche directement, même si le chargement est rapide.
alors que le loading s’affiche si ça prend du temps.
@error
Si une erreur apparaît durant le chargement du @defer, on affiche le contenu de @error.
Déclencheurs
- idle
- viewport
- interaction
- hover
- immediate
- timer
Il existe deux niveaux de controle des déclencheurs :
– le prefetch : quand charge-t-on le bundle
– les triggers optionnels: contrôlent l’affichage
Il existe deux moyens de définir des déclencheurs :
– trigger prédéfinis : on : peut être multiple (dans ce cas-là, ça sera un OR)
– création de trigger customisés : when : condition custom (peut être multiple aussi)
idle
defer est équivalent à on idle, prefetch on idle
immediate
On attend pas que l’état du navigateur soit en idle, c’est direct après le chargement du rendering.
interaction
doit avoir obligatoirement un placeholder non vide !
Si on click dans le placeholder, ça charge l’élément défini dans le @defer !
element sans placeholder
on peut définir un élément du composant, sans placeholder.
A ce moment-là, on va charger le composant uniquement lors de l’interaction de l’élément visé.
viewport
Va déclencher le chargement uniquement quand l’élément sera visible dans le viewport. Fonctionne comme le principe de l’interaction : soit c’est dans le placeholder, soit via un élément nommé dans le composant.
hover
Fonctionne du même principe, mais sur le survol (utilise le mouseenter et le focusin comme événements)
timer
On peut charger en lazy load après un temps défini.
Prefetching
On peut précharger des éléments, et décider de les afficher par la suite.
Par exemple, ci-apres, on va loader le composant à l’idle et l’afficher au hover
avec when
On va pouvoir décider via des booléens quand charger et afficher
Dans ce cas-ci,
- si on clique sur Display : ça va load et afficher;
- si on clique sur Preload : ça va juste charger, et après il faudra cliquer sur Display pour afficher