Skip to content

Nouveautés d'Angular 18 (23 mai 2024)

RIP zone.js ! ⚰️

Historiquement, une bibliothèque appelée zone.js était responsable de déclencher la détection de changement dans Angular. Cette bibliothèque comportait plusieurs inconvénients en termes d'expérience développeur et de performance.

Vous pouvez essayer le support expérimental sans zones dans Angular dès aujourd'hui ! Ajoutez provideExperimentalZonelessChangeDetection à votre démarrage d'application :

typescript
bootstrapApplication(App, {
  providers: [
    provideExperimentalZonelessChangeDetection()
  ]
});

Après avoir ajouté le fournisseur, retirez zone.js de vos polyfills dans angular.json.

Avantages du mode sans zones

L'utilisation de ce mode ouvre de nombreuses possibilités pour les développeurs :

  • Amélioration de la composabilité pour les micro-frontends et l'interopérabilité avec d'autres frameworks.
  • Rendu initial et exécution plus rapides.
  • Taille de bundle réduite et chargement des pages plus rapide.
  • Traces de pile plus lisibles.
  • Débogage simplifié.

Utilisation des signaux dans vos composants

La meilleure façon d'utiliser le mode sans zones dans vos composants est avec des signaux :

typescript
import { Component } from '@angular/core';

@Component({
  standalone: true,
  template: `
    <h1>Bonjour de {{ name() }} !</h1>
    <button (click)="handleClick()">Go Zoneless</button>
  `,
})
export class App {
  protected name = signal('Angular');

  handleClick() {
    this.name.set('Zoneless Angular');
  }
}

Dans l'exemple ci-dessus, cliquer sur le bouton invoque la méthode handleClick, qui met à jour la valeur du signal et met à jour l'interface utilisateur. Cela fonctionne de manière similaire à une application utilisant zone.js, avec quelques différences. Avec zone.js, Angular effectuait une détection de changement chaque fois que l'état de l'application pouvait changer. Sans zones, Angular limite cette vérification à moins de déclencheurs, comme les mises à jour de signaux. Ce changement inclut également un nouveau planificateur avec coalescence pour éviter les vérifications de changements multiples consécutives.

Coalescence par défaut

À partir de la version 18, nous utilisons le même planificateur pour les applications sans zones et les applications utilisant zone.js avec la coalescence activée. Pour réduire le nombre de cycles de détection de changement dans les nouvelles applications zone.js, nous avons également activé la coalescence des zones par défaut.

Ce comportement n'est activé que pour les nouvelles applications car il peut causer des bugs dans les applications dépendant du comportement précédent de détection de changement. La coalescence réduit les cycles de détection de changement inutiles et améliore considérablement les performances de certaines applications.

Pour opter pour la coalescence d'événements dans les projets existants, configurez votre fournisseur NgZone dans bootstrapApplication :

typescript
bootstrapApplication(App, {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true })
  ]
});

Await natif pour les applications sans zones

Zone.js intercepte de nombreux appels de navigateur pour intégrer la détection de changement d'Angular. Malheureusement, async/await est l'une des API que zone.js ne peut pas modifier, et nous devons donc la transformer en promesses via l'Angular CLI. Ce n'est pas optimal car tous les navigateurs modernes prennent en charge async/await, qui sont plus expressifs que les promesses et optimisés par le runtime JavaScript.

Aujourd'hui, si vous créez une application qui utilise la détection de changement expérimentale sans zones, l'Angular CLI utilisera async/await natif sans le transformer en promesses. Cela améliorera le débogage et rendra vos bundles plus petits.

Support du mode sans zones pour les composants

Nous avons activé le support sans zones dans Angular CDK et Angular Material. Cela nous a également aidé à découvrir et à peaufiner certains aspects du modèle sans zones.

Hydratation 🥤

L'hydratation ?

L'hydratation est un processus en développement web où une page rendue côté serveur (SSR) est rendue interactive par le téléchargement et l'exécution du JavaScript nécessaire. Cela permet d'afficher rapidement le contenu statique tout en activant les fonctionnalités interactives une fois le JavaScript chargé. L'hydratation partielle optimise encore plus ce processus en activant progressivement les parties de la page au fur et à mesure qu'elles sont nécessaires, améliorant ainsi les performances, l'expérience utilisateur et le référencement.

Visualiser l'hydratation dans Angular DevTools

À côté de chaque composant se trouve une icône représentant l'état d'hydratation du composant. Pour avoir un aperçu des composants qu'Angular a hydratés sur la page, vous pouvez également activer un mode de superposition. Si votre application présente des erreurs d'hydratation, Angular DevTools les visualisera dans l'explorateur de composants.

Hydratation

Event Replay

La plupart des développeurs n'interagiront pas directement avec le dispatch d'événements, donc voyons pourquoi la relecture des événements est utile. Ci-dessous, vous pouvez voir une maquette d'un simple site e-commerce. Nous avons introduit des délais de chargement artificiels pour simuler une connexion réseau très lente. Imaginez que pendant le chargement de la page, avant qu'elle ne soit hydratée, l'utilisateur souhaite ajouter plusieurs casques à son panier. Si la page n'est pas encore hydratée et donc non interactive, tous les événements utilisateur seraient perdus. À partir de la version 18, en utilisant le dispatch d'événements, Angular commencera à enregistrer les événements utilisateur. Une fois que l'application est hydratée, le dispatch d'événements les rejoue et nous nous retrouvons avec six articles dans le panier.

Event Replay

La fonctionnalité de relecture des événements est disponible en aperçu pour les développeurs dans la version 18. Vous pouvez l'activer en utilisant withEventReplay(), par exemple :

typescript
bootstrapApplication(App, {
  providers: [
    provideClientHydration(withEventReplay())
  ]
});

Avantages de la Relecture des Événements

La relecture des événements permet de s'assurer que les actions des utilisateurs ne sont pas perdues pendant la phase de chargement et d'hydratation de l'application. Cela améliore l'expérience utilisateur, surtout sur des connexions lentes, en garantissant que toutes les interactions sont prises en compte une fois que la page devient interactive.

L'hydratation partielle

Il s'agit d'une technique qui permet d'hydrater votre application de manière incrémentielle après le rendu côté serveur. L'hydratation incrémentielle de votre application permet de charger moins de JavaScript au départ et améliore les performances de votre application.

L'hydratation partielle s'appuie sur les mêmes fondations que les vues différables. Au lieu de rendre le bloc @placeholder sur le serveur comme c'est le cas aujourd'hui, vous pourrez activer un mode où Angular rendra le contenu principal du bloc @defer sur le serveur. Sur le client, Angular téléchargera le JavaScript associé et hydratera un bloc différé uniquement lorsque les conditions de déclenchement spécifiées dans un template seront remplies. Par exemple, voici une API hypothétique :

typescript
@defer (render on server; on viewport) {
  <app-calendar/>
}

Le bloc ci-dessus rendra le composant calendrier sur le serveur. Une fois qu'il atteint le client, Angular téléchargera le JavaScript correspondant et hydratera le calendrier pour le rendre interactif uniquement après qu'il soit entré dans le champ de vision.

Spécification d'un contenu de repli pour ng-content

L'une des demandes les plus votées était de spécifier un contenu par défaut pour ng-content. Dans la version 18, cette fonctionnalité est désormais disponible ! Voici un exemple rapide :

typescript
import { Component } from '@angular/core';

@Component({
  selector: 'app-profile',
  standalone: true,
  template: `
    <ng-content select=".greeting">Bonjour </ng-content>

    <ng-content>Utilisateur inconnu</ng-content>
  `,
})
export class Profile {}

Nous pouvons maintenant utiliser le composant :

html
<app-profile>
  <span class="greeting">Bonjour </span>
</app-profile>

Ce qui donnera :

html
<span class="greeting">Bonjour </span>
Utilisateur inconnu

Événements unifiés de changement d'état des contrôles

Les classes FormControl, FormGroup et FormArray des formulaires Angular exposent désormais une propriété appelée events, qui permet de s'abonner à un flux d'événements pour ce contrôle de formulaire. Cela permet de suivre les changements de valeur, l'état touché, le statut pristine et l'état du contrôle.

Vous pouvez maintenant utiliser :

typescript
const nameControl = new FormControl<string|null>('name', Validators.required);
nameControl.events.subscribe(event => {
  // traiter les événements individuels
});

Abonnez-vous à la newsletter

En juillet, recevez en avant-première notre newsletter avec les dernières actualités, tutoriels, astuces et ressources Angular directement par email !