Użyj podziału kodu na poziomie trasy, aby poprawić wydajność swojej aplikacji.
Z tego posta dowiesz się, jak skonfigurować podział kodu na poziomie trasy w aplikacji Angular, co może zmniejszyć rozmiar pakietu JavaScriptu i znacznie poprawić czas do interakcji.
Przykładowy kod z tego artykułu znajdziesz na GitHub. Przykład routingu z zainteresowaniem jest dostępny w gałęzi chętnie. Przykład podziału kodu na poziomie trasy znajduje się w gałęzi leniwej.
Dlaczego podział kodu ma znaczenie
Rosnąca złożoność aplikacji internetowych prowadził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óźnić interaktywność, dlatego mogą być kosztowne, zwłaszcza na urządzeniach mobilnych.
Najbardziej efektywnym sposobem zmniejszenia pakietów JavaScript bez poświęcania funkcji w aplikacjach jest wdrożenie agresywnego podziału kodu.
Dzielenie kodu pozwala podzielić JavaScript aplikacji na wiele fragmentów powiązanych z różnymi trasami lub funkcjami. Ta metoda powoduje wysyłanie do użytkowników JavaScriptu potrzebnego im podczas wstępnego wczytywania aplikacji, dzięki czemu czas wczytywania jest krótki.
Techniki podziału kodu
Dzielenie kodu można przeprowadzać na 2 poziomach: komponentu i trasy.
- W ramach dzielenia kodu na poziomie komponentu przenosisz komponenty do ich własnych fragmentów JavaScript i wczytujesz je leniwie, gdy są potrzebne.
- W ramach dzielenia kodu na poziomie trasy funkcje każdej trasy dodajesz do osobnego fragmentu. Gdy użytkownicy poruszają się po Twojej aplikacji, pobierają fragmenty powiązane z poszczególnymi trasami i w razie potrzeby uzyskują dostęp do powiązanych funkcji.
Ten post dotyczy konfigurowania podziału na poziomie trasy w Angular.
Przykładowa aplikacja
Zanim zaczniesz korzystać z 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 zrefaktoryzować trasę samodzielną nyan
.
W wersji 8.1.0 interfejsu wiersza poleceń Angular wykonaj te czynności za Ciebie:
ng g module nyan --module app --route nyan
Wygeneruje to:
– Nowy moduł routingu o nazwie NyanModule
– Trasa w regionie AppModule
o nazwie nyan
, która będzie dynamicznie ładować NyanModule
- Trasa domyślna w tunelu NyanModule
– Komponent o nazwie NyanComponent
, który zostanie wyrenderowany, gdy użytkownik trafi na trasę domyślną
Wykonajmy te czynności ręcznie, aby lepiej zrozumieć, jak działa dzielenie kodu w Angular.
Gdy użytkownik przejdzie na trasę nyan
, router wyświetli w gniazdku routera NyanComponent
.
Aby użyć podziału kodu na poziomie trasy w Angular, ustaw właściwość loadChildren
deklaracji trasy 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 gotowej trasy:
- 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
.
Powyższy fragment kodu określa, że gdy użytkownik przejdzie do nyan
, narzędzie Angular powinno dynamicznie ładować plik nyan.module
z katalogu nyan
i wyrenderować komponent powiązany z trasą domyślną 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 element NyanComponent
, gdy użytkownik przechodzi do strony https://example.com/nyan
.
Aby sprawdzić, czy router Angular pobiera plik nyan.module
leniwie w Twoim ś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
pojawi się na karcie sieci.
Ten przykład znajdziesz na GitHubie.
Pokaż wskaźnik postępu
Obecnie, gdy użytkownik klika przycisk NYAN, aplikacja nie wskazuje, ż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 wskaźnika wewnątrz elementu router-outlet
w tagu 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
w przypadku wykrycia zdarzenia RouteConfigLoadStart
i ustawi flagę na false
w przypadku wykrycia zdarzenia 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 wynoszące 500 ms, aby pokazać, jak działa wskaźnik postępu.
Podsumowanie
Możesz zmniejszyć rozmiar pakietu aplikacji Angular, stosując podział kodu na poziomie trasy:
- 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.