Dans l’univers des frameworks JavaScript front-end, la majorité des comparatifs se concentrent sur la syntaxe, les outils de développement ou la taille de la communauté. Pourtant, un facteur bien plus fondamental les différencie : la manière dont ils détectent les changements de l’état applicatif (change detection) pour mettre à jour l’interface utilisateur. Ce choix architectural influence l’expérience développeur, l’expérience utilisateur, la surface d’API, la satisfaction de la communauté et son implication. En examinant chaque framework sous cet angle, il devient possible de déterminer celui qui convient le mieux à un projet et à ses utilisateurs.

React : une gestion explicite de l’état

React repose sur un principe simple : “Je gère l’état pour savoir quand il change.” Le développeur modifie l’état en appelant directement l’API du framework via des fonctions comme setCount retournée par useState. Puisque React est averti de la modification, il sait qu’il doit lancer un nouveau rendu du composant. Le moteur React utilise ensuite un algorithme de diffing du DOM virtuel pour déterminer quelles parties de la page doivent être mises à jour. Cette approche nécessite d’inclure le runtime React dans le bundle téléchargé par l’utilisateur. Le principe, décliné au fil des ans des classes composants aux hooks, reste le même.

Angular : de la détection automatique au casse-tête

Angular, de son côté, semble au premier abord effectuer la détection automatiquement. Il utilise NgZone pour observer les actions de l’utilisateur et, par défaut, vérifie l’intégralité de l’arborescence des composants à chaque événement. Cette stratégie naïve entraîne des problèmes de performance dès que l’application atteint une taille raisonnable. Pour y remédier, Angular propose une alternative : la stratégie OnPush. Avec elle, c’est au développeur d’informer le framework, via ChangeDetectorRef.markForCheck(), qu’un changement asynchrone a eu lieu. Cette approche devient rapidement ingérable sur des applications complexes. La documentation officielle oriente alors vers l’utilisation d’observables RxJS combinés à AsyncPipe, qui souscrit automatiquement à l’observable et notifie le détecteur de changements à chaque nouvelle valeur émise. Les observables sont puissants pour modéliser des flux de valeurs, mais leur courbe d’apprentissage est raide, ils sont difficiles à déboguer, et ils sont surdimensionnés pour des cas simples comme l’état binaire d’une case à cocher. Pour pallier ces limites, l’équipe Angular travaille sur une nouvelle approche appelée Signals, conceptuellement proche des stores de Svelte, qui reprend le principe de React : le framework prend le contrôle de l’état pour en surveiller les changements et optimiser les rendus.