Angular : La détection des changements
La détection des changements dans une application Angular est cruciale pour maintenir une expérience utilisatrice fluide et performante. Que vous soyez un développeur débutant ou expérimenté, comprendre les mécanismes de détection des changements dans Angular peut considérablement améliorer la réactivité et l’efficacité de votre application. Dans cet article, nous explorerons en profondeur les techniques et les meilleures pratiques pour optimiser la détection des changements dans Angular, tout en vous fournissant des conseils pratiques pour intégrer ces méthodes dans vos projets actuels. Découvrez comment Angular facilite ce processus grâce à ses outils intégrés, tels que les signaux, et apprenez à tirer parti de cette nouvelle fonctionnalité pour créer des applications performantes.
Angular nous offre plusieurs stratégies pour la détection de changements. Commençons par la stratégie par défaut pour bien comprendre d’où nous partons.
La stratégie par défaut
Depuis sa création, Angular utilise zone.js pour la détection de changement. zone.js est une bibliothèque qui fournit un mécanisme de zone et un contexte d’exécution. En d’autres termes, il fournit des outils qui permettent de suivre l’état de notre application. zone.js va notifier Angular qui, via son service NgZone mettra à jour le DOM en conséquences.
Pour entrer un peu plus dans les détails de cette stratégie, il vous faudra visualiser un arbre des composants avec à la racine app.component.
Pour planifier la détection des changements, Angular, par le biais de ngZone, partira de notre composant racine pour ensuite examiner chaque composant de l’arborescence. Si zone.js notifie d’une modification dans l’arborescence, NgZone s’occupera alors de déclencher la mise à jour de la vue. Cela assure que les modifications sont détectées et propagées dans toute la hiérarchie des composants selon les besoins.
Avec la ChangeDetectionStragery.Default, l’application parcourt tous les composants ce qui peut poser problème en matière de performances. En effet, il parcourra des composants qui n’ont pas changé ou même qui n’ont pas forcément vocation à voir leurs DOM modifiés.
Pour cela, une autre stratégie permet de filtrer pour indiquer quels composants doivent être vérifiée pour la détection des changements et surtout à certaines conditions.
La stratégie OnPush
En complément de la stratégie par défaut, la team Angular a intégré une autre stratégie qui permet d’exécuter la détection de changement sur un sous-ensemble de l’arborescence des composants uniquement. Avec la ChangeDetectionStragery.OnPush , vous pouvez ignorer la détection des changements par défaut sur un sous-ensemble de votre arborescence de composants.
En effet, la détection de changement OnPush demande à Angular de lancer la détection uniquement à certaines conditions.
Premièrement, il va falloir ajouter au décorateur @Component notre stratégie de détection de changement OnPush.
Ensuite, pour qu’Angular détecte un changement dans notre composant, il faudra que notre composant obtienne une nouvelle entrée. Par exemple, à chaque fois qu’un élément @Input est modifié, notre DOM sera mis à jour normalement comme avec la stratégie par défaut.
De plus, il est possible de marquer un composant pour que zone.js l’intègre à son prochain tour de détection. Pour cela, il existe la méthode markForCheck() de changeDetector.
Avec le code ci-dessus, Angular va alors vérifier les changements de notre composant et mettre à jour le DOM toutes les secondes.
À savoir aussi que la stratégie OnPush permet de vérifier les changements de notre composant uniquement s’il existe une nouvelle instance d’un objet de notre composant.
Mais bien que cette stratégie semble plus avantageuse et optimisée que la stratégie par défaut, le team Angular a introduit une autre manière bien plus simple et optimisée de détecter les changements. C’est ce que nous allons voir dans la dernière partie.
La stratégie des signaux (Signal)
Introduits durant la version 16, les signaux sont apparu pour atteindre deux objectifs.
Le premier était bien sur d’améliorer les performances des applications Angular.
Le second objectif est lié au premier, il est de se passer définitivement de zone.js dans une version future. En effet, l’équipe d’Angular à depuis maintenant un certain moment émit le souhait de se séparer de zone.js pour sa détection de changement. C’est pour cela que les signaux sont apparu donc à la version 16 et que la version 18 introduit un support expérimental sans zone.js provideExperimentalZonelessChangeDetection qui permets de tester pleinement la puissance des signaux dans le contexte de votre application.
Mais concrètement, comment fonctionne les signaux ?
Un signal apporte un avantage considérable, il va notifier directement Angular quand il sera modifié, grâce à cela, plus besoin de parcourir toute l’arborescence des composants, Angular n’a plus qu’à mettre à jour la vue correspondante.
L’API des signaux (signal) introduite par Angular pour cette nouvelle stratégie de changement est plutôt simple à utiliser.
Pour commencer, il faudra importer signal de la bibliothèque @angular/core comme ci-dessous :
Ensuite, pour créer un signal, c’est assez simple :
Après cela, mySignal sera donc égal à 2. Pour ce qui est du type de notre signal, il peut, dans notre cas, être déduit. C’est-à-dire que mySignal sera de type number et qu’ajouter un type générique n’est pas nécessaire. Attention, il y a des cas ou le type ne seront pas déduits et il devra alors être précisé.
Maintenant que nous avons créé notre premier signal, appelons-le dans le template de notre composant :
Petite habitude à prendre rapidement, il ne faudra pas oublier les parenthèses que vous souhaiter appeler un signal dans le HTML.
Nous pouvons modifier la valeur de notre signal. Pour cela, nous appelons la méthode set(). Cela va avoir pour effet d’écraser la valeur précédente.
Vous pouvez aussi vouloir mettre à jour un signal en fonction de sa valeur actuelle. Pour cela, on utilise la méthode update().
La fonction fléchée passe alors la valeur actuelle du signal pour pouvoir ensuite lui passer des opérations.
Les signaux nous permettent aussi d’aller encore plus loin avec les signaux calculés. En d’autres termes, cela nous permet de créer un signal qui dépend de la valeur d’un ou plusieurs autres signaux.
Dans le code ci-dessus, nous créons donc un signal nommé completedTaskCountqui récupérera la totalité des tâches grâce à un autre signal getAllTasks.
Pour conclure, l’API des signaux est une véritable révolution pour Angular mais aussi pour le monde des frameworks Javascript (en effet, Angular est le premier à introduire cela). Comme dit précédemment, les signaux vont permettre de se passer de zone.js qui est couteux en matière de performances, ils vont aussi permettre de simplifier grandement la détection de changement. Même si pour l’instant, Angular n’oblige pas encore à utiliser les signaux, je vous conseille grandement de les utiliser et de vous familiariser avec car cela ne devrait pas tarder.