Lazy Loading von Feature-Modulen mit Angular
Die Performanz einer Web-Anwendung spielt stets eine wichtige Rolle. In diesem Artikel soll es darum gehen das initiale Laden der Anwendung so schnell wie möglich zu gestalten. Denn kein Anwender wartet gerne auf eine Anwendung bis diese endlich geladen ist.
Natürlich gibt es einige Möglichkeiten die Performanz einer Anwendung zu verbessern. Dieser Artikel gibt einen guten Überblick über die verschiedenen Aspekte, die eine Rolle spielen. Thema dieses Artikels ist das Lazy Loading von Angular Modulen.
Eine Sache noch vorweg. Der gesamte Quellcode ist auf Github zu finden. Einfach auschecken und schon habt ihr ein lauffähiges Beispiel.
Grundsätzliches
Wenn ich von Angular Modulen rede, dann sind immer die Klassen gemeint, die mit dem @NgModules Dekorator beschriftet sind. Ein solches Modul kann beliebig viele Angular-Artefakte enthalten (Komponenten, Services, Pipes, Directives, ...). Ratsam ist es immer nicht nur ein großes Modul pro Anwendung zu definieren, sondern die Anwendung in mehrere Module zu schneiden. Eine klare und saubere Strukturierung des Quellcodes hat wie bekannt unzählige Vorteile. Im Angular Umfeld ist der Rahmen eines Moduls häufig eine Route. Bedeutet konkret, dass es unser Ziel ist einzelne Module unserer Anwendung zu definierten Zeitpunkten nachzuladen. Durch den späteren Zeitpunkt des Ladens der verschiedenen Module haben wir den Vorteil, dass der initiale Ladevorgang weniger JavaScript lädt und deswegen schneller vonstatten geht.
Der Einfachheit halber fangen wir im nachfolgenden Beispiel auf der grünen Wiese an.
Das Beispiel
ng new angular-lazy-loading --routing
ng generate module lazy-loaded --route lazy-loaded-route --module app.module
Das erzeugte Modul hat den Namen LazyLoadedModule. Die Route wird in der URL über den Namen lazy-loaded-route erreichbar sein. Durch die --module Angabe wird das neue Modul dem AppRoutingModule bekanntgemacht. Schauen wir uns als erstes das AppModule an.
@NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
const routes: Routes = [ { path: 'lazy-loaded-route', loadChildren: () => import('./lazy-loaded/lazy-loaded.module').then(m => m.LazyLoadedModule) } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule {}
Hier im AppRoutingModule ist das Modul LazyLoadedModule zu finden. Der ng generate module Befehl hat automatisch die Route so definiert, dass diese per Lazy Loading nachgeladen werden kann. Wir müssen also nichts weiter dafür tun, um einen Nachlade-Mechanismus zu implementieren.
Im Prinzip war's das schon! Als letzten Schritt passen wir noch die app.component.html Datei an. Hier fügen wir eine Verlinkung zur lazy-loaded-route hinzu, damit man zwischen den Routen wechseln kann.
Inhalt der app.component.html:
<h1> {{title}} </h1> <button routerLink="/lazy-loaded-route">Lazy Loaded Route</button> <button routerLink="">Home</button> <router-outlet></router-outlet>
Ziel erreicht
Das Werk ist vollbracht. Erst wenn die Route betreten wird, werden die notwendigen Applikationsdateien der Route geladen.
Wir haben somit erreicht, dass das kompilierte JavaScript des LazyLoadedModule nicht Teil des initialen Ladevorgangs der Anwendung ist. Das zu ladene JavaScript, um die Seite aufzurufen, ist also kleiner, als wenn wir nur ein einzelnes großes Modul definiert hätten.
Ende
Senior Chief Consultant bei ORDIX
Kommentare
Bei Updates im Blog, informieren wir per E-Mail.