Aller au contenu principal

Angular

Signaux et mode zoneless avec Angular 22 : ce qui change pour une application existante

Le mode zoneless supprime le déclenchement automatique des mises à jour. Concrètement, cela rend visibles les rendus inutiles et impose de revoir la façon dont l'état circule dans l'application.

- 10 min de lecture

Pendant des années, le déclenchement des mises à jour dans Angular reposait sur une règle simple : toute tâche asynchrone terminée provoquait une vérification de l'arbre de composants. Pratique, mais coûteuse : une requête HTTP, un minuteur ou un événement de socket relançaient une vérification qui n'avait souvent aucun effet visible.

Angular 22 rend le mode zoneless utilisable en production. Est-ce une bonne idée sur une application existante ? Oui, à condition de traiter la migration comme un travail d'architecture et non comme un changement de configuration.

Ce que le mode zoneless change réellement

Sans zone.js, Angular ne sait plus qu'une donnée a changé : il faut le lui dire. Les signaux remplissent ce rôle, mais uniquement à l'intérieur du système de signaux. Un objet modifié par mutation après un appel réseau classique ne déclenchera aucun rendu. Ce n'est pas un défaut : c'est précisément ce qui rend le comportement prévisible.

@Component({
  selector: 'app-order-list',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class OrderListComponent {
  private readonly ordersService = inject(OrdersService);

  readonly filter = signal<OrderFilter>({ status: 'OPEN', page: 0 });

  readonly orders = toSignal(
    toObservable(this.filter).pipe(
      switchMap(filter => this.ordersService.search(filter)),
    ),
    { initialValue: [] as Order[] },
  );

  readonly total = computed(() =>
    this.orders().reduce((sum, order) => sum + order.amount, 0),
  );

  onStatusChange(status: OrderStatus): void {
    this.filter.update(current => ({ ...current, status }));
  }
}

Migrer par étapes plutôt que globalement

La migration que nous appliquons se déroule en quatre étapes, dans cet ordre précis, chaque étape restant livrable en production.

  • Activer la détection de changements explicite sur les composants les plus sollicités.
  • Convertir les états locaux en signaux, en commençant par les filtres et les compteurs.
  • Remplacer les abonnements manuels par des signaux dérivés, en supprimant chaque appel explicite au marquage de vérification.
  • Retirer zone.js du démarrage de l'application et surveiller les écrans les plus complexes.

Le piège des mises à jour venues de l'extérieur

Les bibliothèques tierces et certaines API du navigateur restent hors du système de signaux : gestionnaires d'événements de carte, lecteurs vidéo, websockets encapsulés. Chaque point d'entrée externe doit être converti explicitement en signal, faute de quoi l'écran se figera silencieusement. Recenser ces points avant de démarrer évite une phase de débogage longue et frustrante.

Le rendu serveur et le mode zoneless

Le rendu serveur bénéficie directement de cette évolution. Le serveur attend que l'application soit stable avant d'envoyer la page ; sans zone.js, cette stabilité dépend uniquement des signaux et des requêtes en cours, ce qui réduit les attentes inutiles. Côté back-end, la pagination et le filtrage doivent rester côté serveur pour tirer parti de ce gain.

@GetMapping("/orders")
Page<OrderResponse> search(@Valid OrderSearchCriteria criteria, Pageable pageable) {
    return orderSearch.search(criteria, pageable).map(OrderResponse::from);
}
PratiqueAvec zone.jsEn mode zoneless
Mise à jour après un appel HTTPAutomatiqueExplicite via un signal
Coût d'un événement sans effet visuelVérification complète de l'arbreAucune vérification
État partagé entre composantsSouvent un sujet par composantSignal fourni par un service
Diagnostic d'un écran figéRarePoint d'entrée externe oublié
Le mode zoneless ne rend pas une application rapide : il rend visible chaque mise à jour déclenchée pour rien.

Mesurer avant de généraliser

Nous mesurons trois indicateurs avant et après migration : le temps d'interaction sur les écrans de liste, le nombre de cycles de rendu sur un scénario répétable, et le temps de stabilisation du rendu serveur. Ces mesures déterminent s'il faut poursuivre sur les écrans restants ou s'arrêter à un périmètre intermédiaire.

Sur les applications que nous avons accompagnées, le gain le plus net ne vient pas du mode zoneless lui-même mais du nettoyage qu'il impose : abonnements non libérés, état dupliqué, et composants qui se réabonnaient à chaque interaction. C'est ce travail qui produit la différence mesurable.

  • Angular SSR
  • Performance
  • Playwright
  • Signals Angular

Articles associes