Angular er en JavaScript-framework til frontend-applikationer, der er udviklet af Google til at bygge skalerbare webapplikationer i virksomhedskvalitet. Nogle af disse applikationer kan blive ret store, hvilket påvirker indlæsningstiden for din applikation.

For at reducere indlæsningstiden og forbedre den samlede oplevelse for dine brugere kan du bruge en teknik, der kaldes lazy loading. Denne native Angular-funktion giver dig mulighed for kun at indlæse de nødvendige dele af webappen først og derefter indlæse andre moduler efter behov.

I denne artikel vil du lære om lazy loading, og hvordan det kan hjælpe med at fremskynde din webapp.

Hvad er lazy loading?

Lazy loading henviser til teknikken til kun at indlæse websideelementer, når de er nødvendige. Dens modstykke er eager loading, hvor alt indlæses – eller forsøger at indlæse – med det samme. En for ivrig hentning af alle billeder, videoer, CSS og JavaScript-kode kan betyde lange indlæsningstider – ikke godt for brugerne.

Lazy loading bruges ofte til billeder og videoer på websteder, der er vært for en masse indhold. I stedet for at indlæse alle medier på én gang, hvilket ville bruge en masse båndbredde og forplumre sidevisningerne, indlæses disse elementer, når deres placering på siden er ved at rulle ind til visning.

Angular er et framework for applikationer med en enkelt side, som er baseret på JavaScript til en stor del af sin funktionalitet. Din app’s samling af JavaScript kan nemt blive stor, efterhånden som app’en vokser, og det medfører en tilsvarende stigning i dataforbrug og indlæsningstid. For at fremskynde tingene kan du bruge lazy loading til først at hente de nødvendige moduler og udskyde indlæsningen af andre moduler, indtil der er brug for dem.

Fordele ved lazy loading i Angular

Lazy loading giver fordele, der gør dit websted mere brugervenligt. Disse omfatter bl.a:

  • Hurtigere indlæsningstid: JavaScript indeholder instruktioner til visning af din side og indlæsning af dens data. På grund af dette er det en ressource, der blokerer for rendering. Det betyder, at browseren skal vente på at indlæse alt JavaScript, før din side kan vises. Ved lazy loading i Angular opdeles JavaScript i stykker, som indlæses separat. Den første chunk indeholder kun logik, der er nødvendig for sidens hovedmodul. Det indlæses ivrigt, hvorefter de resterende moduler indlæses lazily. Ved at reducere størrelsen af den indledende chunk får du siden til at indlæses og gengives hurtigere.
  • Mindre dataforbrug: Ved at opdele dataene i chunks og indlæse efter behov bruger du muligvis mindre båndbredde.
  • Bevarede browserressourcer: Da browseren kun indlæser de chunks, der er nødvendige, spilder den ikke hukommelse og CPU på at fortolke og gengive kode, der ikke er nødvendig.

Implementering af lazy loading i Angular

For at følge med i denne tutorial skal du bruge følgende:

  • NodeJS installeret
  • Grundlæggende kendskab til Angular

Opstart dit projekt

Du skal bruge Angular CLI til at oprette dit projekt. Du kan installere CLI’en ved hjælp af npm ved at køre kommandoen:

npm install -g @angular/cli

Derefter opretter du et projekt med navnet Lazy Loading Demo som følger:

ng new lazy-loading-demo --routing

Denne kommando opretter et nyt Angular-projekt, komplet med routing. Du vil udelukkende arbejde i mappen src/app, som indeholder koden til din app. Denne mappe indeholder din vigtigste routing-fil, app-routing.module.ts. Strukturen i mappen skal se således ud:

Skærmbillede: Angular mappestrukturen vist i en terminal.
Mappestrukturen i et Angular-projekt.

Oprettelse af et funktionsmodul med ruter

Dernæst skal du oprette et funktionsmodul, der skal lazy loades. For at oprette dette modul skal du køre denne kommando:

ng generate module blog --route blog --module app.module

Denne kommando opretter et modul ved navn BlogModule, sammen med routing. Hvis du åbner src/app/app-routing.module.ts , vil du se, at det nu ser således ud:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [ { path: 'blog', loadChildren: () => import('./blog/blog.module').then(m => m.BlogModule) }];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { } 

Den del, der er vigtig for lazy loading, er den tredje linje:

const routes: Routes = [ { path: 'blog', loadChildren: () => import('./blog/blog.module').then(m => m.BlogModule) }];

Denne linje definerer ruterne. Ruten til bloggen bruger loadChildren -argumentet i stedet for component. loadChildren -argumentet fortæller Angular, at ruten skal lazy loades – at modulet kun skal importeres dynamisk, når ruten besøges, og derefter returneres til routeren. Modulet definerer sine egne underordnede ruter, f.eks. blog/**, i filen routing.module.ts. Det blogmodul, du genererede, ser således ud:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { BlogComponent } from './blog.component';

const routes: Routes = [{ path: '', component: BlogComponent }];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class BlogRoutingModule { }

Du vil bemærke, at denne routing-fil indeholder en enkelt rute, ''. Denne er opløst til /blog og peger på BlogComponent. Du kan tilføje flere komponenter og definere disse ruter i denne fil.

Hvis du f.eks. ønsker at tilføje en komponent, der kan hente detaljer om et bestemt blogindlæg, kan du oprette komponenten med denne kommando:

ng generate component blog/detail

Det genererer komponenten til blogdetaljerne og tilføjer den til blogmodulet. Hvis du vil tilføje en rute til den, kan du blot tilføje den til dit routes-array:

const routes: Routes = [{ path: '', component: BlogComponent },
                        {path:"/:title",component: DetailComponent}];

Dette tilføjer en rute, der opløser for blog/:title (f.eks. blog/angular-tutorial). Dette array af ruter er lazy-loaded og er ikke inkluderet i det oprindelige bundle.

Bekræft lazy loading

Du kan nemt kontrollere, at lazy loading fungerer, ved at køre ng serve og observere output. Nederst i dit output bør du få noget i stil med dette:

Skærmbillede: Output af Angulars ng serve-kommando i terminalen.
Verificering af lazy loading ved hjælp af Angular’s ng serve.

Ovenstående output er opdelt i to dele: Initial Chunk Files er de filer, der indlæses, når siden først indlæses. Lazy Chunk Files er lazy-loaded. Blogmodulet er opført i dette eksempel.

Kontrol af lazy loading gennem browserens netværkslogfiler

En anden måde at bekræfte lazy loading på er ved at bruge fanen Netværk i din browsers panel Udviklingsværktøjer. (På Windows er det F12 i Chrome og Microsoft Edge og CtrlShiftI i Firefox. På en Mac er det CommandOptionI i Chrome, Firefox og Safari.)

Vælg filteret JS for kun at få vist JavaScript-filer, der er indlæst via netværket. Efter den første indlæsning af appen bør du få noget, der ligner dette:

Skærmbillede: Angular JavaScript-filer logget i udviklerværktøjer.
Den første log over JavaScript-downloads, der er vist i Developer Tools.

Når du navigerer til /blog, vil du bemærke, at der er indlæst en ny chunk, src_app_blog_blog_module_ts.js. Det betyder, at dit modul kun blev anmodet om, da du navigerede til denne rute, og at det bliver lazy loaded. Netværksloggen bør se nogenlunde sådan her ud:

Skærmbillede: Opdateret visning af Angular JavaScript-filer, der er logget i udviklerværktøjer.
Lazy-loaded modul vises i downloads logget af Developer Tools.

Lazy Loading vs Eager Loading

Lad os til sammenligning også oprette et modul med ivrig indlæsning og se, hvordan det påvirker filstørrelsen og indlæsningstiden. For at demonstrere dette vil du oprette et modul til autentificering. Et sådant modul skal muligvis indlæses ivrigt, da autentificering er noget, som du måske kræver, at alle brugere skal gøre.

Generer et AuthModule ved at køre denne kommando i CLI’en:

ng generate module auth --routing --module app.module

Det genererer modulet og en routing-fil. Den tilføjer også modulet til filen app.module.ts. Men i modsætning til den kommando, vi brugte til at generere et modul sidste gang, tilføjer denne kommando ikke en lazy-loaded route. Den bruger parameteren --routing i stedet for --route <name>. Det tilføjer autentifikationsmodulet til imports -arrayet i app.module.ts:

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    AuthModule //added auth module
  ],
  providers: [],
  bootstrap: [AppComponent]
})

Tilføjelse af AuthModule til dit AppModule imports array betyder, at autentificeringsmodulet tilføjes til de oprindelige chunk-filer og vil blive inkluderet sammen med JavaScript-hovedbundlen. For at verificere dette kan du køre ng serve igen og observere output:

Skærmbillede: Vinklede scripts efter at godkendelsesmodulet er tilføjet.
Output af Angular’s ng serve kommando efter tilføjelse af godkendelsesmodulet.

Som du kan se, er autentifikationsmodulet ikke inkluderet som en del af de lazy chunk-filer. Derudover er størrelsen af det oprindelige bundle steget. Filen main.js er næsten fordoblet i størrelse, idet den er steget fra 8 KB til 15 KB. I dette eksempel er stigningen lille, da komponenterne ikke indeholder meget kode. Men efterhånden som du fylder komponenterne med logik, vil denne filstørrelse stige, hvilket er et godt argument for lazy loading.

Opsummering

Du har lært, hvordan du kan bruge lazy loading i Angular til kun at hente moduler, når de er nødvendige. Lazy loading er en fantastisk teknik til at forbedre indlæsningstider, reducere dataforbruget og bedre udnytte dine frontend- og backend-ressourcer.

Lazy loading vil sammen med teknologi som content delivery network og minifying JavaScript forbedre både dit websteds ydeevne og dine brugeres tilfredshed.

Hvis du er ved at udvikle et WordPress-websted og virkelig vil skrue op for hastigheden, kan du læse om Kinsta Edge Caching for at se nogle imponerende tal.

Michael Nyamande

A digital product manager by day, Michael is a tech enthusiast who is always tinkering with different technologies. His interests include web and mobile frameworks, NoCode development, and blockchain development.