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

  1. Folder By Feature

  2. Lazy Loading

  3. Détection de changement OnPush

  4. Ahead Of Time Compilation

  5. Après ?

  6. 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

  1. Supprimer l’import module dans le AppModule

  2. Modifier le routing du AppModule pour utiliser loadChildren

  3. 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

Differential Loading

Deux versions de l'application créées:

  1. Version ES6 via l'attribut type="module"
  2. 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:

 

  1. Un browser non compatible ES6 est listé dans browserslist
  2. 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

  • 896