Podział kodu na poziomie trasy w Angular

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 komponentupoziomie 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:

  1. Ustawiono loadChildren zamiast component. Dzieląc kod na poziomie trasy, musisz wskazywać moduły ładowane dynamicznie, a nie komponenty.
  2. Gdy obietnica zostanie rozwiązana w loadChildren, zwracasz wartość NyanModule, a nie wskazujesz NyanComponent.

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:

  1. Naciśnij „Control + Shift + J” (lub „Command + Option + J” na Macu), aby otworzyć Narzędzia deweloperskie.
  2. Kliknij kartę Sieć.

  3. W przykładowej aplikacji kliknij NYAN.

  4. Pamiętaj, że plik nyan-nyan-module.js pojawia się na karcie Sieć.

Łatwo wczytywanie pakietów JavaScript dzięki dzieleniu kodu na poziomie przekierowań

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ń:

  1. Użyj generatora leniwego ładowania modułu interfejsu wiersza poleceń Angular do automatycznego tworzenia rusztowania dynamicznie ładowanej trasy.
  2. Dodaj wskaźnik ładowania, gdy użytkownik nawiguje na leniwą trasę, aby pokazać, że trwa działanie.