Appearance
Nouveautés d'Angular 17
Dans la version 17, les développeurs Angular sont heureux de présenter :
- Des vues différées qui améliorent considérablement les performances et l'expérience développeur.
- Une exécution jusqu'à 90 % plus rapide grâce aux boucles de contrôle intégrées dans les benchmarks publics.
- Une construction jusqu'à 87 % plus rapide pour le rendu hybride et 67 % pour le rendu côté client.
- Une nouvelle apparence reflétant les fonctionnalités tournées vers l'avenir d'Angular.
- Un tout nouveau parcours d'apprentissage interactif.
- ...et des dizaines d'autres fonctionnalités et améliorations !
Contrôle de flux intégré
Pour améliorer l'expérience des développeurs, les développeurs Angular ont introduit une nouvelle syntaxe de modèle de bloc offrant des fonctionnalités puissantes avec des API simples et déclaratives. Sous le capot, le compilateur Angular transforme cette syntaxe en instructions JavaScript efficaces pouvant exécuter des flux de contrôle, du chargement différé, et plus encore.
Les développeurs Angular ont utilisé cette nouvelle syntaxe de bloc pour un flux de contrôle intégré optimisé. Après avoir mené des études utilisateurs, il a été identifié que de nombreux développeurs avaient des difficultés avec *ngIf, *ngSwitch, et *ngFor. Après avoir recueilli des retours de la communauté, des partenaires et mené des études UX, un nouveau flux de contrôle intégré pour Angular a été développé !
Le flux de contrôle intégré permet :
- Une syntaxe plus ergonomique, plus proche de JavaScript, donc plus intuitive, nécessitant moins de recherches dans la documentation.
- Un meilleur contrôle de type grâce à un rétrécissement de type plus optimal.
- Une réduction de l'empreinte d'exécution (jusqu'à 30 kilooctets de moins), améliorant les scores des Core Web Vitals.
- Une disponibilité automatique dans les templates sans importations supplémentaires.
- Des améliorations significatives des performances.
Instructions conditionnelles
Comparons côte à côte avec *ngIf :
html
<div *ngIf="loggedIn; else anonymousUser">
L'utilisateur est connecté
</div>
<ng-template #anonymousUser>
L'utilisateur n'est pas connecté
</ng-template>
Avec l'instruction if
intégrée, cette condition ressemble à :
angular-html
@if (loggedIn) {
L'utilisateur est connecté
} @else {
L'utilisateur n'est pas connecté
}
Fournir directement le contenu pour @else
est une simplification majeure par rapport à la clause else
de l'alternative *ngIf. Le flux de contrôle actuel permet également d'avoir @else if
, ce qui était historiquement impossible.
L'ergonomie améliorée est encore plus visible avec *ngSwitch :
html
<div [ngSwitch]="accessLevel">
<admin-dashboard *ngSwitchCase="admin"/>
<moderator-dashboard *ngSwitchCase="moderator"/>
<user-dashboard *ngSwitchDefault/>
</div>
qui avec le flux de contrôle intégré devient :
angular-html
@switch (accessLevel) {
@case ('admin') { <admin-dashboard/> }
@case ('moderator') { <moderator-dashboard/> }
@default { <user-dashboard/> }
}
Le nouveau flux de contrôle permet un rétrécissement de type significativement meilleur dans les branches individuelles de @switch
, ce qui n'est pas possible avec *ngSwitch.
Boucle for
intégrée
Une des mises à jour favorites est la boucle for
intégrée, qui en plus d'améliorer l'expérience développeur, pousse la vitesse de rendu d'Angular à un autre niveau !
Sa syntaxe de base est :
angular-html
@for (user of users; track user.id) {
{{ user.name }}
} @empty {
Liste d'utilisateurs vide
}
Les développeurs rencontrent souvent des problèmes de performance dans les applications en raison de l'absence de fonction trackBy
dans *ngFor. Quelques différences avec @for
sont que track
est obligatoire pour assurer une performance de différenciation rapide. De plus, c'est beaucoup plus facile à utiliser car ce n'est qu'une expression plutôt qu'une méthode dans la classe du composant. La boucle @for
intégrée a également un raccourci pour les collections avec zéro élément via un bloc @empty
optionnel.
Vues différées
Parlons maintenant de l'avenir du chargement différé ! En tirant parti de la nouvelle syntaxe de bloc, les développeurs Angular ont développé un nouveau mécanisme puissant pour rendre vos applications plus rapides. Les vues différées permettent un chargement différé déclaratif et puissant avec une ergonomie sans précédent.
Supposons que vous avez un blog et que vous souhaitez charger paresseusement la liste des commentaires des utilisateurs. Actuellement, vous devez utiliser ViewContainerRef
tout en gérant toute la complexité des nettoyages, de la gestion des erreurs de chargement, de l'affichage d'un espace réservé, etc. Prendre en compte divers cas particuliers peut entraîner du code non trivial, difficile à tester et à déboguer.
Les nouvelles vues différées permettent de charger paresseusement la liste des commentaires et toutes leurs dépendances transitoires avec une seule ligne de code déclaratif :
angular-html
@defer {
<comment-list />
}
La partie la plus incroyable est que tout cela se passe via une transformation à la compilation : Angular abstrait toute la complexité en trouvant les composants, directives et pipes utilisés dans un bloc @defer
, générant des importations dynamiques et gérant le processus de chargement et de transition entre les états.
Commencer à charger paresseusement un composant lorsqu'un certain élément du DOM entre dans le viewport implique beaucoup plus de logique non triviale et l'API IntersectionObserver
. Angular rend l'utilisation des IntersectionObservers
aussi simple que d'ajouter un déclencheur de vue différée !
angular-html
@defer (on viewport) {
<comment-list />
} @placeholder {
<!-- Contenu de l'espace réservé à afficher jusqu'à ce que les commentaires se chargent -->
<img src="comments-placeholder.png">
}
Dans l'exemple ci-dessus, Angular rend d'abord le contenu du bloc @placeholder
. Lorsqu'il devient visible dans le viewport, le chargement du composant <comment-list/>
commence. Une fois le chargement terminé, Angular supprime l'espace réservé et rend le composant.
Il existe également des blocs pour les états de chargement et d'erreur :
angular-html
@defer (on viewport) {
<comment-list/>
} @loading {
Chargement…
} @error {
Échec du chargement :(
} @placeholder {
<img src="comments-placeholder.png">
}
Voilà ! Il y a une tonne de complexité sous le capot que Angular gère pour vous.
Les vues différées offrent quelques déclencheurs supplémentaires :
on idle
— charge paresseusement le bloc lorsque le navigateur n'effectue pas de tâches lourdeson immediate
— commence automatiquement le chargement différé, sans bloquer le navigateuron timer(<time>)
— retarde le chargement avec un minuteuron viewport
eton viewport(<ref>)
— viewport permet également de spécifier une référence pour un élément d'ancrage. Lorsque l'élément d'ancrage est visible, Angular charge paresseusement le composant et le rendon interaction
eton interaction(<ref>)
— permet de déclencher le chargement différé lorsque l'utilisateur interagit avec un élément particulieron hover
eton hover(<ref>)
— déclenche le chargement différé lorsque l'utilisateur survole un élémentwhen <expr>
— permet de spécifier votre propre condition via une expression booléenne
Les vues différées offrent également la possibilité de précharger les dépendances avant de les rendre. Ajouter le préchargement est aussi simple que d'ajouter une instruction prefetch
au bloc defer
et prend en charge tous les mêmes déclencheurs.
angular-html
@defer (on viewport; prefetch on idle) {
<comment-list />
}
Les vues différées sont disponibles en aperçu pour les développeurs dans la version 17 dès aujourd'hui ! Pour en savoir plus sur cette fonctionnalité, consultez ce guide.
Nouveau package @angular/ssr
Les développeurs Angular ont déplacé le dépôt Angular Universal vers le dépôt Angular CLI et rendu le rendu côté serveur encore plus intégré à l'offre d'outils !
À partir d'aujourd'hui, pour ajouter la prise en charge du rendu hybride à votre application existante, exécutez :
sh
ng add @angular/ssr
Cette commande générera le point d'entrée du serveur, ajoutera les capacités de construction SSR et SSG, et activera l'hydratation par défaut. @angular/ssr
offre une fonctionnalité équivalente à @nguniversal/express-engine
, actuellement en mode maintenance. Si vous utilisez le express-engine
, Angular CLI mettra automatiquement à jour votre code vers @angular/ssr
.
Virgin Media O2 a observé une augmentation de 112 % des ventes après être passé à la dernière solution de rendu hybride Angular depuis leur plateforme héritée, avec une réduction moyenne du décalage cumulatif de mise en page de 99,4 % en utilisant NgOptimizedImage
aux côtés de Angular SSR
avec hydratation du DOM.
Déployer votre application avec SSR
Pour améliorer encore l'expérience des développeurs, les développeurs Angular ont travaillé en étroite collaboration avec les fournisseurs de cloud
pour permettre un déploiement fluide sur leurs plateformes.
Firebase reconnaîtra et déploiera automatiquement votre application Angular avec une configuration quasi nulle, avec l'aperçu précoce de son nouveau CLI conscient du framework.
sh
firebase experiments:enable webframeworks
firebase init hosting
firebase deploy
Le CLI conscient du framework reconnaît l'utilisation de SSR, i18n, l'optimisation des images et plus encore — vous permettant de servir des applications web performantes sur une infrastructure sans serveur et économique.
Pour ceux qui ont des monorepos Angular complexes ou qui préfèrent simplement les outils natifs, AngularFire permet le déploiement sur Firebase avec ng deploy
:
sh
ng add @angular/fire
ng deploy
Pour permettre le déploiement sur des travailleurs de bord, les développeurs Angular ont activé la prise en charge des modules ECMAScript dans le rendu côté serveur d'Angular, introduit un backend fetch pour HttpClient, et travaillé avec CloudFlare pour simplifier le processus.
Nouveaux hooks de cycle de vie
Pour améliorer les performances du SSR et du SSG d'Angular, à long terme, les développeurs Angular souhaitent s'éloigner de l'émulation DOM et des manipulations directes du DOM. En même temps, la plupart des applications doivent interagir avec les éléments pour instancier des bibliothèques tierces, mesurer la taille des éléments, etc.
Pour permettre cela, les développeurs Angular ont développé un ensemble de nouveaux hooks de cycle de vie :
afterRender
— enregistre un rappel à invoquer chaque fois que l'application termine le renduafterNextRender
— enregistre un rappel à invoquer la prochaine fois que l'application termine le rendu
Seul le navigateur invoquera ces hooks, ce qui vous permet de brancher une logique DOM personnalisée en toute sécurité directement dans vos composants. Par exemple, si vous souhaitez instancier une bibliothèque de graphiques, vous pouvez utiliser afterNextRender
:
typescript
@Component({
selector: 'my-chart-cmp',
template: `<div #chart>{{ ... }}</div>`,
})
export class MyChartCmp {
@ViewChild('chart') chartRef: ElementRef;
chart: MyChart|null;
constructor() {
afterNextRender(() => {
this.chart = new MyChart(this.chartRef.nativeElement);
}, {phase: AfterRenderPhase.Write});
}
}
Chaque hook prend en charge une valeur de phase (par exemple, read, write) qu'Angular utilisera pour planifier les rappels afin de réduire les changements de mise en page et améliorer les performances.
Vite et esbuild par défaut pour les nouveaux projets
Les développeurs Angular n’auraient pas pu activer le SSR dans Angular dès le départ sans les changements fondamentaux apportés à la pipeline de construction d'Angular CLI !
Dans la version 16, les développeurs Angular ont introduit une préversion du nouvel environnement de build alimenté par esbuild et Vite. Depuis, de nombreux développeurs l'ont expérimenté et certains partenaires d'entreprise ont rapporté une amélioration du temps de build de 67 % dans certaines de leurs applications ! Aujourd'hui, les développeurs Angular sont heureux d'annoncer que le nouveau constructeur d'applications passe de la préversion à une fonctionnalité activée par défaut pour toutes les nouvelles applications !
De plus, les développeurs Angular ont mis à jour la pipeline de construction pour le rendu hybride. Avec SSR et SSG, vous pouvez observer jusqu'à 87 % d'amélioration de la vitesse pour ng build
et une boucle d'édition-mise à jour 80 % plus rapide pour ng serve
.
Comparaison de performance
Comparaison de la nouvelle pipeline de construction esbuild + Vite avec la pipeline héritée basée sur webpack:
Dans une future version mineure, les développeurs Angular fourniront des schémas pour migrer automatiquement les projets existants utilisant le rendu hybride (rendu côté client avec SSG ou SSR). Si vous souhaitez tester le nouveau constructeur d'application dès aujourd'hui, consultez ce guide dans notre documentation.
Débogage de l'injection de dépendances dans DevTools
L'année dernière, les développeurs Angular ont montré une préversion des capacités de débogage de l'injection de dépendances dans Angular DevTools. Au cours des derniers mois, ils ont implémenté de toutes nouvelles API de débogage permettant de se brancher dans le runtime du framework et d'inspecter l'arbre des injecteurs.
Basés sur ces API, les développeurs Angular ont construit une interface utilisateur d'inspection permettant de prévisualiser les éléments suivants :
- Les dépendances de vos composants dans l'inspecteur de composants.
- L'arbre des injecteurs et le chemin de résolution des dépendances.
- Les fournisseurs déclarés dans les injecteurs individuels.
Vous pouvez trouver un aperçu rapide des fonctionnalités dans l'animation ci-dessous:
API autonomes dès le départ
Après avoir recueilli des retours sur les composants, directives et pipes autonomes au cours de l'année et demie passée, et en ayant peaufiné leur expérience développeur, les développeurs Angular sont confiants pour les activer dès le début dans toutes les nouvelles applications. Toutes les commandes ng generate
généreront désormais des composants, directives et pipes autonomes.
En parallèle, les développeurs Angular ont également révisé l'ensemble de la documentation sur angular.io et angular.dev pour garantir une expérience d'apprentissage cohérente, des pratiques de développement et des recommandations.
Les développeurs Angular conserveront les NgModules pour le futur prévisible, mais voyant les avantages des nouvelles API autonomes, ils recommandent fortement de migrer progressivement vos projets vers ces nouvelles API. Un schéma est également disponible pour automatiser la majeure partie de cette transition :
sh
ng generate @angular/core:standalone
Support expérimental des transitions de vue
L'API des transitions de vue permet des transitions fluides lors des changements de DOM. Dans le routeur Angular, les développeurs Angular fournissent désormais un support direct pour cette API via la fonctionnalité withViewTransitions
. En utilisant cela, vous pouvez utiliser les capacités natives du navigateur pour créer des transitions animées entre les routes.
Vous pouvez ajouter cette fonctionnalité à votre application dès aujourd'hui en la configurant dans la déclaration du fournisseur du routeur lors de l'initialisation :
typescript
bootstrapApplication(App, {
providers: [
provideRouter(routes, withViewTransitions()),
]
});
withViewTransitions
accepte un objet de configuration optionnel avec une propriété onViewTransitionCreated
, qui est un callback vous offrant un contrôle supplémentaire :
- Décider si vous souhaitez ignorer certaines animations
- Ajouter des classes au document pour personnaliser l'animation et les supprimer lorsque l'animation est terminée
- Etc.
Préconnexion automatique dans la directive d'image
La directive d'image Angular génère désormais automatiquement des liens de préconnexion pour les domaines que vous avez fournis en tant qu'argument au chargeur d'image. Si la directive d'image ne peut pas identifier automatiquement une origine et ne détecte pas de lien de préconnexion pour l'image LCP, elle émettra un avertissement pendant le développement.
En savoir plus sur cette fonctionnalité dans le guide de la directive d'image.
Chargement différé du module d'animations
Cette fonctionnalité peut réduire de 60 Ko votre bundle initial (16 Ko gzippé). Le contributeur de la communauté Matthieu Riegler a proposé et mis en œuvre une fonctionnalité permettant de charger paresseusement le module d'animation via une fonction de fournisseur asynchrone :
typescript
import { provideAnimationsAsync } from '@angular/platform-browser/animations-async';
bootstrapApplication(RootCmp, {
providers: [provideAnimationsAsync()]
});
Transformations des valeurs d'entrée
Un modèle courant consiste à avoir un composant qui reçoit une entrée booléenne. Cependant, cela impose des contraintes sur la manière dont vous pouvez passer une valeur à un tel composant. Par exemple, si nous avons la définition suivante d'un composant Expander :
typescript
@Component({
standalone: true,
selector: 'my-expander',
template: `…`
})
export class Expander {
@Input() expanded: boolean = false;
}
...et que nous essayons de l'utiliser comme :
html
<my-expander expanded/>
Vous obtiendrez une erreur indiquant que "la chaîne de caractères n'est pas assignable à un booléen". Les transformations des valeurs d'entrée permettent de corriger cela en configurant le décorateur d'entrée :
typescript
@Component({
standalone: true,
selector: 'my-expander',
template: `…`
})
export class Expander {
@Input({ transform: booleanAttribute }) expanded: boolean = false;
}
Vous pouvez trouver les demandes de fonctionnalités originales sur GitHub — Propriétés booléennes en tant qu'attributs binaires HTML et Propriétés booléennes en tant qu'attributs binaires HTML.
Style et styleUrls en chaînes de caractères
Les composants Angular supportent plusieurs feuilles de style par composant. Cependant, dans la majorité des cas, lorsque je veux styliser mes composants, je crée un tableau avec un seul élément pointant vers les styles en ligne ou référençant une feuille de style externe. Une nouvelle fonctionnalité permet de passer de :
typescript
@Component({
styles: [`
...
`]
})
...
@Component({
styleUrls: ['styles.css']
})
...
...à une syntaxe plus simple et plus logique :
typescript
@Component({
styles: `
...
`
})
...
@Component({
styleUrl: 'styles.css'
})
...
Schémas communautaires
Pour soutenir le développement des schémas communautaires, les développeurs Angular ont livré quelques méthodes utilitaires dans le package @schematics/angular/utility
. Vous pouvez maintenant importer une expression directement dans la racine d'une application Angular et ajouter un fournisseur à la racine d'une application Angular, en plus de la fonctionnalité existante d'ajout de dépendance à package.json
.