Podział kodu na poziomie trasy w Angular

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:

  1. Ustawiono loadChildren zamiast component. Dzieląc kod na poziomie trasy, musisz wskazywać moduły ładowane dynamicznie, a nie komponenty.
  2. Po rozwiązaniu obietnicy w narzędziu loadChildren zwracasz wartość NyanModule, zamiast wskazywać NyanComponent.

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:

  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 pojawi się na karcie sieci.

Leniwe ładowanie pakietów JavaScript z podziałem kodu na poziomie trasy

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:

  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.