Popraw wydajność swojej aplikacji, używając podziału kodu na poziomie trasy.
W tym poście wyjaśniamy, jak skonfigurować w aplikacji Angular dzielenie kodu na poziomie trasy, co może zmniejszyć rozmiar pakietu JavaScript i znacznie skrócić czas do pełnej interaktywności.
Przykładowy kod z tego artykułu znajdziesz na GitHub. Przykład routingu z żądaniem jest dostępny w gałęzi zainteresowań. Przykład podziału kodu na poziomie trasy znajduje się w leniwej gałęzi.
Dlaczego dzielenie kodu jest takie ważne
Rosnąca złożoność aplikacji internetowych powoduje znaczny wzrost ilości kodu JavaScript wysyłanego do użytkowników. Duże pliki JavaScript mogą zauważalnie opóźniać interaktywność, przez co mogą być kosztowne, zwłaszcza na urządzeniach mobilnych.
Najskuteczniejszym sposobem zmniejszenia pakietów JavaScript bez rezygnacji z funkcji aplikacji jest agresywny podział kodu.
Dzielenie kodu umożliwia podzielenie kodu JavaScript aplikacji na kilka fragmentów związanych z różnymi trasami lub funkcjami. Ta metoda wysyła użytkownikom kod JavaScript tylko podczas początkowego wczytywania aplikacji, co skraca czas wczytywania.
Techniki podziału kodu
Podział kodu może odbywać się na 2 poziomach: na poziomie komponentu i poziomu trasy.
- W przypadku podziału kodu na poziomie komponentu przenosisz komponenty do ich własnych fragmentów JavaScriptu, a w razie potrzeby wczytujesz je leniwie.
- W przypadku podziału kodu na poziomie trasy zamykasz funkcjonalność każdej trasy w osobnym fragmencie. Gdy użytkownicy poruszają się po Twojej aplikacji, pobierają fragmenty powiązane z poszczególnymi trasami i w razie potrzeby otrzymują powiązane funkcje.
Ten post dotyczy konfigurowania podziału na poziomie trasy w Angular.
Przykładowa aplikacja
Zanim dowiemy się, jak używać podziału kodu na poziomie trasy w Angular, przyjrzyjmy się przykładowej aplikacji:
Sprawdź implementację modułów aplikacji. W elemencie AppModule
zdefiniowane są 2 trasy: domyślna trasa powiązana z HomeComponent
i trasa nyan
powiązana z NyanComponent
:
@NgModule({
...
imports: [
BrowserModule,
RouterModule.forRoot([
{
path: '',
component: HomeComponent,
pathMatch: 'full'
},
{
path: 'nyan',
component: NyanComponent
}
])
],
...
})
export class AppModule {}
Podział kodu na poziomie trasy
Aby można było skonfigurować podział kodu, trzeba refaktoryzować trasę żądania nyan
.
Interfejs wiersza poleceń Angular w wersji 8.1.0 może wykonać wszystko za pomocą tego polecenia:
ng g module nyan --module app --route nyan
Spowoduje to wygenerowanie:
– nowego modułu routingu o nazwie NyanModule
– trasy w AppModule
o nazwie nyan
, która będzie dynamicznie wczytywać trasę NyanModule
;
– trasy domyślnej w NyanModule
;
– komponentu o nazwie NyanComponent
, który zostanie wyrenderowany, gdy użytkownik wybierze trasę domyślną.
Wykonajmy te czynności ręcznie, aby lepiej zrozumieć, jak działa podział kodu w Angular.
Gdy użytkownik przejdzie na trasę nyan
, router wyrenderuje NyanComponent
w gniazdku routera.
Aby w Angular użyć podziału kodu na poziomie trasy, ustaw w deklaracji trasy właściwość loadChildren
i połącz ją z importem dynamicznym:
{
path: 'nyan',
loadChildren: () => import('./nyan/nyan.module').then(m => m.NyanModule)
}
Istnieją 2 główne różnice w stosunku do tej drogi:
- Ustawienie
loadChildren
zamiastcomponent
. Gdy używasz podziału kodu na poziomie trasy, musisz wskazywać moduły ładowane dynamicznie, a nie komponenty. - W usłudze
loadChildren
, gdy obietnica zostanie zrealizowana, zwracasz wartośćNyanModule
, zamiast wskazaćNyanComponent
.
Powyższy fragment kodu określa, że gdy użytkownik przechodzi do nyan
, Angular powinno dynamicznie wczytywać nyan.module
z katalogu nyan
i renderować komponent powiązany z trasą domyślną zadeklarowaną w module.
Możesz powiązać trasę domyślną z komponentem za pomocą tej deklaracji:
import { NgModule } from '@angular/core';
import { NyanComponent } from './nyan.component';
import { RouterModule } from '@angular/router';
@NgModule({
declarations: [NyanComponent],
imports: [
RouterModule.forChild([{
path: '',
pathMatch: 'full',
component: NyanComponent
}])
]
})
export class NyanModule {}
Ten kod renderuje kod NyanComponent
, gdy użytkownik przechodzi do aplikacji https://example.com/nyan
.
Aby sprawdzić, czy router Angular pobiera nyan.module
leniwie w środowisku lokalnym:
- Naciśnij „Control + Shift + J” (lub „Command + Option + J” na Macu), aby otworzyć Narzędzia deweloperskie.
Kliknij kartę Sieć.
Kliknij NYAN w przykładowej aplikacji.
Pamiętaj, że plik
nyan-nyan-module.js
jest widoczny na karcie Sieć.
Ten przykład znajdziesz na GitHubie.
Pokaż wskaźnik postępu
W tej chwili, gdy użytkownik kliknie przycisk NYAN, aplikacja nie wskazuje, że wczytuje kod JavaScript w tle. Aby przekazać użytkownikowi opinię podczas ładowania skryptu, warto dodać wskaźnik postępu.
Aby to zrobić, zacznij od dodania znacznika wskaźnika wewnątrz elementu router-outlet
w języku app.component.html
:
<router-outlet>
<span class="loader" *ngIf="loading"></span>
</router-outlet>
Następnie dodaj klasę AppComponent
do obsługi zdarzeń routingu. Ta klasa ustawi flagę loading
na true
, gdy usłyszy zdarzenie RouteConfigLoadStart
, i ustawi flagę na false
, gdy wykryje zdarzenie RouteConfigLoadEnd
.
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
loading: boolean;
constructor(router: Router) {
this.loading = false;
router.events.subscribe(
(event: RouterEvent): void => {
if (event instanceof NavigationStart) {
this.loading = true;
} else if (event instanceof NavigationEnd) {
this.loading = false;
}
}
);
}
}
W poniższym przykładzie wprowadziliśmy sztuczne opóźnienie wynoszące 500 ms, aby można było zobaczyć działanie wskaźnika postępu.
Podsumowanie
Możesz zmniejszyć rozmiar pakietu aplikacji Angular, stosując podział kodu na poziomie trasy:
- Użyj generatora modułów leniwego ładowania w interfejsie wiersza poleceń Angular, aby automatycznie tworzyć rusztowanie dynamicznej trasy.
- Dodaj wskaźnik wczytywania, gdy użytkownik przechodzi na leniwą trasę, aby pokazać, że trwa działanie.