Angular 18 : zoneless change detection

🏷️ Front-end 📅 12/04/2026 16:00:00 👤 Mezgani said
Angular Angular 18 Zoneless Change Detection Zone.js
Angular 18 : zoneless change detection

Abandonnez Zone.js avec Angular 18 : comprenez le mode zoneless, configurez provideExperimentalZonelessChangeDetection et boostez les performances.

Le problème de Zone.js

Depuis la naissance d'Angular, Zone.js est la bibliothèque qui "patche" les APIs asynchrones du navigateur (setTimeout, Promises, XHR, etc.) pour déclencher automatiquement la détection de changements après chaque opération asynchrone.

Si Zone.js fonctionne bien, il comporte des inconvénients :

  • Bundle size : ~150 KB ajoutés à chaque application
  • Overhead : chaque opération asynchrone déclenche potentiellement une détection de changements complète
  • Débogage : les stack traces sont polluées par Zone.js
  • Compatibilité : certaines APIs modernes (Signals, streams) ne fonctionnent pas bien avec le patching
A retenir : Zone.js est un héritage d'Angular 2 (2016). En 2024, les Signals offrent un meilleur modèle de réactivité qui rend Zone.js inutile.

Principe du mode zoneless

En mode zoneless, Angular ne patch plus les APIs asynchrones. La détection de changements se déclenche uniquement quand :

  • Un signal change de valeur
  • Un composant appelle explicitement markForCheck()
  • Un event handler DOM est déclenché dans un composant Angular
  • Un async pipe émet une nouvelle valeur

Cela signifie qu'Angular ne vérifie que les composants qui ont réellement changé, et non l'arbre entier à chaque tick.

Configuration dans Angular 18

Pour activer le mode zoneless, modifiez votre app.config.ts :

import { ApplicationConfig } from '@angular/core';
import { provideExperimentalZonelessChangeDetection } from '@angular/core';

export const appConfig: ApplicationConfig = {
  providers: [
    provideExperimentalZonelessChangeDetection(),
    // ... autres providers
  ]
};

Ensuite, retirez Zone.js du polyfills dans angular.json :

// angular.json
{
  "projects": {
    "my-app": {
      "architect": {
        "build": {
          "options": {
            "polyfills": []  // Supprimer "zone.js"
          }
        }
      }
    }
  }
}
Note : En Angular 18, le mode zoneless est encore expérimental (Experimental). Il devient stable progressivement dans Angular 19 et 20.

Pourquoi les signaux sont indispensables

Sans Zone.js, Angular ne sait plus "automatiquement" quand l'état a changé. Les signaux deviennent le mécanisme principal de notification :

@Component({
  selector: 'app-counter',
  standalone: true,
  template: `
    <p>Compteur : {{ count() }}</p>
    <button (click)="increment()">+1</button>
  `
})
export class CounterComponent {
  count = signal(0);

  increment() {
    this.count.update(v => v + 1);
    // Angular détecte le changement via le signal
    // Pas besoin de Zone.js
  }
}

Quand count.update() est appelé, Angular sait exactement quel composant a besoin d'être mis à jour — uniquement CounterComponent.

markForCheck() et ChangeDetectorRef

Pour les composants qui n'utilisent pas de signaux (code legacy, bibliothèques tierces), markForCheck() reste disponible :

@Component({ ... })
export class LegacyComponent {
  data: any;

  constructor(
    private service: DataService,
    private cdr: ChangeDetectorRef
  ) {}

  ngOnInit() {
    this.service.getData().subscribe(result => {
      this.data = result;
      this.cdr.markForCheck(); // notifie Angular manuellement
    });
  }
}

Gains de performances

Les applications en mode zoneless avec signaux montrent des améliorations mesurables :

  • Bundle initial : -150 KB (Zone.js supprimé)
  • Temps de démarrage : réduit car aucun patching des APIs au bootstrap
  • Détection de changements : granulaire au niveau du signal, pas de check global
  • Memory : moins d'allocations liées au patching des Promises/XHR
A retenir : Le mode zoneless est le futur d'Angular. Commencez dès maintenant à utiliser les signaux dans vos nouveaux composants pour préparer la migration.