Zwiększ wydajność aplikacji, stosując podział kodu na poziomie przekierowania.
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ładowy kod 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 doprowadziła do znacznego zwiększenia ilości treści w języku JavaScript wysyłanych do użytkowników. Duże pliki JavaScript mogą znacznie opóźniać interaktywność, co może być kosztowne, zwłaszcza na urządzeniach mobilnych.
Najbardziej efektywnym sposobem zmniejszenia pakietów JavaScript bez poświęcania funkcji w aplikacjach jest zastosowanie agresywnego podziału 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 ramach dzielenia kodu na poziomie trasy funkcje każdej trasy dodajesz do osobnego fragmentu. 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 aplikacji AppModule
zdefiniowane są 2 trasy: domyślna trasa powiązana z adresem HomeComponent
oraz trasa nyan
powiązana z adresem NyanComponent
:
@NgModule({
...
imports: [
BrowserModule,
RouterModule.forRoot([
{
path: '',
component: HomeComponent,
pathMatch: 'full'
},
{
path: 'nyan',
component: NyanComponent
}
])
],
...
})
export class AppModule {}
Dzielenie kodu na poziomie trasy
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 gniazdku routera.
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)
}
Trzeba jednak pamiętać o 2 głównych różnicach w stosunku do fascynującej podróży:
- Ustawiono
loadChildren
zamiastcomponent
. Dzieląc kod na poziomie trasy, musisz wskazywać moduły ładowane dynamicznie, a nie komponenty. - Gdy obietnica zostanie rozwiązana w
loadChildren
, zwracasz wartośćNyanModule
, 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.
Możesz powiązać trasę domyślną z komponentem, korzystając z 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:
- Naciśnij „Control + Shift + J” (lub „Command + Option + J” na Macu), aby otworzyć Narzędzia deweloperskie.
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 podczas wczytywania skryptu przekazywać użytkownikom opinie, 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 leniwego ładowania modułu interfejsu wiersza poleceń Angular do automatycznego tworzenia rusztowania dynamicznie ładowanej trasy.
- Dodaj wskaźnik ładowania, gdy użytkownik nawiguje na leniwą trasę, aby pokazać, że trwa działanie.