Zwiększ wydajność aplikacji, stosując podział kodu na poziomie przekierowań.
Z tego artykułu dowiesz się, jak skonfigurować dzielenie kodu na poziomie przekierowań w aplikacji Angular. Dzięki temu możesz zmniejszyć rozmiar pakietu JavaScript i znacznie poprawić czas do interakcji.
Przykłady kodu z tego artykułu znajdziesz na GitHub. Przykład dynamicznego kierowania jest dostępny w gałęzi eager. Przykład podziału kodu na poziomie przekierowań znajduje się w gałęzi leniwej.
Dlaczego podział kodu ma znaczenie
Rosnąca złożoność aplikacji internetowych spowodowała znaczny wzrost ilości kodu JavaScript dostarczanego użytkownikom. Duże pliki JavaScript mogą znacznie opóźniać interaktywność, co może być kosztownym zasobem, zwłaszcza na urządzeniach mobilnych.
Najskuteczniejszym sposobem na zmniejszenie rozmiaru pakietów JavaScript bez rezygnacji z funkcji w aplikacjach jest zastosowanie agresywnego dzielenia kodu.
Dzielenie kodu umożliwia podzielenie kodu JavaScript aplikacji na wiele fragmentów powiązanych z różnymi ścieżkami lub funkcjami. Dzięki temu użytkownicy otrzymują tylko kod JavaScript potrzebny do wczytania aplikacji, co skraca czas wczytywania.
Techniki podziału kodu
Dzielenie kodu może odbywać się na 2 poziomach: poziomie komponentu i poziomie trasy.
- W przypadku dzielenia kodu na poziomie komponentu przenosisz komponenty do ich własnych fragmentów kodu JavaScript i wczytujesz je w miarę potrzeby.
- W przypadku podziału kodu na poziomie trasy funkcje każdej trasy są umieszczane w osobnym fragmencie. Gdy użytkownicy poruszają się po aplikacji, pobierają fragmenty powiązane z poszczególnymi ścieżkami i uzyskiwanie powiązanych funkcji, gdy jest to potrzebne.
W tym poście skupiamy się na konfigurowaniu podziału na poziomie trasy w Angular.
Przykładowa aplikacja
Zanim omówimy stosowanie dzielenia kodu na poziomie trasy w Angular, przyjrzyjmy się przykładowej aplikacji:
Sprawdź implementację modułów aplikacji. W AppModule
zdefiniowano 2 trasy: domyślną trasę powiązaną z HomeComponent
i trasę nyan
powiązaną z NyanComponent
:
@NgModule({
...
imports: [
BrowserModule,
RouterModule.forRoot([
{
path: '',
component: HomeComponent,
pathMatch: 'full'
},
{
path: 'nyan',
component: NyanComponent
}
])
],
...
})
export class AppModule {}
Dzielenie kodu na poziomie przekierowań
Aby skonfigurować podział kodu, musisz przerobić gotową ścieżkę nyan
.
Wersja 8.1.0 interfejsu wiersza poleceń Angular może wykonać wszystko za Ciebie 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ć NyanModule
; – domyślnej trasy w NyanModule
; – komponentu o nazwie NyanComponent
, który zostanie wyrenderowany, gdy użytkownik kliknie domyślną trasę.
Wykonaj te czynności ręcznie, aby lepiej zrozumieć implementację dzielenia kodu za pomocą Angulara.
Gdy użytkownik przejdzie do trasy nyan
, router wyrenderuje NyanComponent
w swoim gnieździe.
Aby w Angular korzystać z dzielenia kodu na poziomie ścieżki, ustaw właściwość loadChildren
w deklaracji ścieżki i połącz ją z importem dynamicznym:
{
path: 'nyan',
loadChildren: () => import('./nyan/nyan.module').then(m => m.NyanModule)
}
W porównaniu z metodą bezpośrednią występują 2 podstawowe różnice:
- Zamiast
component
ustawionoloadChildren
. Jeśli korzystasz z dzielenia kodu na poziomie przekierowań, musisz wskazywać moduły wczytywane dynamicznie, a nie komponenty. - W
loadChildren
, gdy spełnisz obietnicę, zwracaszNyanModule
, a nie wskazujeszNyanComponent
.
Fragment kodu powyżej określa, że gdy użytkownik przechodzi do nyan
, Angular powinien dynamicznie wczytywać nyan.module
z katalogu nyan
i renderować komponent powiązany z domyślną ścieżką zadeklarowaną w module.
Trasę domyślną możesz powiązać 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 NyanComponent
, gdy użytkownik przechodzi do https://example.com/nyan
.
Aby sprawdzić, czy router Angular pobiera nyan.module
w sposób leniwy w środowisku lokalnym:
- Aby otworzyć Narzędzia dla programistów, naciśnij `Control+Shift+J` (lub `Command+Option+J` na Macu).
Kliknij kartę Sieć.
W przykładowej aplikacji kliknij NYAN.
Pamiętaj, że plik
nyan-nyan-module.js
pojawia się na karcie Sieć.
Ten przykład znajdziesz na GitHubie.
Wyświetlanie spinnera
Obecnie, gdy użytkownik kliknie przycisk NYAN, aplikacja nie informuje, że wczytuje JavaScript w tle. Aby wyświetlić użytkownikowi informacje podczas wczytywania skryptu, warto dodać wskaźnik postępu.
Aby to zrobić, zacznij od dodania znacznika dla wskaźnika w elemencie router-outlet
w elemencie app.component.html
:
<router-outlet>
<span class="loader" *ngIf="loading"></span>
</router-outlet>
Następnie dodaj klasę AppComponent
, aby obsługiwać zdarzenia kierowania. Ta klasa ustawia flagę loading
na true
, gdy usłyszy zdarzenie RouteConfigLoadStart
, i na false
, gdy usłyszy 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 przykładzie poniżej wprowadziliśmy sztuczne opóźnienie 500 ms, aby można było zobaczyć działanie spinnera.
Podsumowanie
Rozmiar pakietu aplikacji Angular możesz zmniejszyć, stosując podział kodu na poziomie przekierowań:
- Użyj generatora modułów z opóźnionym ładowaniem w interfejsie wiersza poleceń Angulara, aby automatycznie utworzyć szablon ścieżki ładowanej dynamicznie.
- Dodaj wskaźnik wczytywania, gdy użytkownik przejdzie do leniwej trasy, aby pokazać, że trwa działanie.