Vers l'infini et au-delà avec Angular !
William Marques @wylmarq
William Marques
- Consultant FullStack @IpponTech
- JHipster Angular Stream Leader
- Java Lover
William Marques
- Consultant FullStack @IpponTech
- JHipster Angular Stream Leader
Java Lover- JavaScript Lover
1 Full Day of JHipster
Core Team Members
Amazing speakers
"C'est le bordel"
Comment faire scaler son architecture ?
Comment la garder lisible ?
Comment s'assurer des performances de mon application ?
"On s'en fout on a la fibre"
Software Disenchantment
Regardez autour de vous : nos ordinateurs portables sont mille fois plus puissants que ceux qui ont emmené l’Homme sur la Lune.
Et pourtant, les pages web ont du mal à maintenir une vitesse de défilement constante de 60 fps sur la dernière version du MacBook Pro.
Solutions
-
Folder By Feature
-
Lazy Loading
-
Détection de changement OnPush
-
Ahead Of Time Compilation
-
Après ?
-
Webpack Bundle Analyzer
Folder By Feature
Découpage en couches techniques
Dans les habitudes, notamment dans le monde Java, mais pas conseillé pour Angular
Exemple:
Un dossier components
Un dossier services
...
Code des features non centralisé
Trop de fichiers !
Folder By Feature
-
MaFeature
Composant
Service
Module
Modèle
Si code partagé entre les features, placer le code dans le SharedModule
Exemple
Heroes: Feature
Shared: Composants/directives/pipes/Services partagés
Importé dans tous les features modules
Mon application fait 10Mo et met 10s à charger sur mobile...
Lazy Loading
Pourquoi ?
Ne fournir à l’utilisateur que ce dont il a besoin.
Exemple:
Mon application a un super dashboard d’administration avec des graphiques
95% de mes utilisateurs ne sont pas administrateurs, inutile de leur faire télécharger la librairie de graphiques !
Mise en place
-
Supprimer l’import module dans le AppModule
-
Modifier le routing du AppModule pour utiliser loadChildren
-
Placer les routes du module dans son routing module
const routes: Routes = [
{
path: 'home',
component: HomeComponent
},
{ path: 'admin', loadChildren: './admin/admin.module#AdminModule' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
Démo !
Aller plus loin
Stratégies de chargements:
- Charger en tâche de fond: PreloadAllModules
- Stratégie custom: Implémenter PreloadingStrategy
Utilisation:
@NgModule({
imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })],
exports: [RouterModule]
})
export class AppRoutingModule { }
Encore plus loin
Précharger les modules visibles sur la page
ngx-quicklink
Utilisation:
@NgModule({
imports: [RouterModule.forRoot(routes, { preloadingStrategy: QuicklinkStrategy })],
exports: [RouterModule]
})
export class AppRoutingModule { }
Mon application démarre super vite !
Mais rame quand je navigue...
😢
OnPush
OnPush ?
Indique à Angular que le composant doit se mettre à jour uniquement lorsque la référence de ses Inputs changera
L’objet passé en Input doit donc être immutable !
Moins de détection de changement
De meilleures performances !
Démo !
Ahead Of Time Compilation
Les deux types de compilation
Just In Time (JIT): La compilation de l’application se fait au runtime, dans le navigateur
Ahead Of Time (AOT): La compilation de l’application se fait au build
Pourquoi ?
Rendering plus rapide: Pas d’étape de compilation
Détection d’erreurs en amont: AOT vérifie les bindings dans les templates et permet d’éviter les erreurs au runtime
Avant
Après
Comment l'activer
Avec le CLI: ng build --aot
Activée par défaut lors du ng build --prod
Sans le CLI: Utiliser @ngtools/webpack
Configuration Webpack
import {AngularCompilerPlugin} from '@ngtools/webpack'
exports = { /* ... */
module: {
rules: [
{
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
loader: '@ngtools/webpack'
}
]
},
plugins: [
new AngularCompilerPlugin({
tsConfigPath: 'path/to/tsconfig.json',
entryModule: 'path/to/app.module#AppModule'
})
]
}
Et après ?
Angular 8
Nouveau moteur de rendu: Ivy
Payload réduit
Rétrocompatible
Debug facilité (notamment dans les templates)
Toujours en cours de développement
Activable dans Angular 8
Angular 8
Nouvelle syntaxe pour le lazy loading !
Plus proche du standard dynamic imports
{ path: 'admin', loadChildren: './admin/admin.module#AdminModule' }
{ path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) }
Differential Loading
Support d'ES6 dans les navigateurs
Source: https://caniuse.com/#feat=es6
Differential Loading
Deux versions de l'application créées:
- Version ES6 via l'attribut type="module"
- Version ES5 via l'atttribut nomodule
Bundle plus léger pour les navigateurs modernes (ES5+)
Navigateurs legacy toujours supportés
Pour l'activer
Angular CLI produira un bundle ES5 à deux conditions:
- Un browser non compatible ES6 est listé dans browserslist
- La version target de typescript est à es2015 ou es6
Webpack Bundle Analyzer
Pourquoi ?
Analyser ce que contient ses bundles JavaScript
Identifier rapidement les librairies volumineuses
Trouver des alternatives: bundlephobia
Comment ?
Avec le CLI:
ng build --prod --stats-json
npx webpack-bundle-analyzer dist/sample-app/stats.json
Sans le CLI:
webpack --profile --json > stats.json
npx webpack-bundle-analyzer stats.json
Démo !
Ca fait beaucoup...
JHipster
Générateur d'application
Angular / React / Vue + Spring Boot
Toutes les bonnes pratiques déjà incluses !
Folder by feature
Lazy Loading
Optimisations Webpack
Librairies populaires présentes
Bootstrap
Moment
Font Awesome
JHipster
En plus:
Génération d'entités (Back + Front)
Architecture micro-services
Déploiement cloud (GCP, Azure, AWS...)
Gestion de l'authentification
Et plein d'autres choses !
Questions ?
[MIXIT] Vers l'infini et au-delà avec Angular
By William Marques
[MIXIT] Vers l'infini et au-delà avec Angular
- 1,021