Angular 中的路徑層級程式碼分割

使用路徑層級程式碼分割功能,提升應用程式效能!

本文說明如何在 Angular 應用程式中設定路徑層級的程式碼分割,以縮減 JavaScript 套件大小並大幅縮短互動所需時間

您可以在 GitHub 上找到本文提供的程式碼範例。您可以在 eager 分支版本中找到 Eager 轉送範例。路徑層級程式碼分割範例位於「Lazy 分支版本」中。

程式碼分割的重要性

網頁應用程式日益複雜,因此提供給使用者的 JavaScript 數量大幅增加。大型的 JavaScript 檔案可能會大幅延遲互動,因此會耗費大量資源,特別是在行動裝置上。

如要在不犧牲應用程式功能的情況下縮減 JavaScript 套件,最有效率的方法,就是採用積極的程式碼分割功能。

程式碼分割功能可讓您將應用程式的 JavaScript 分為多個與不同路徑或功能相關聯的區塊。這種方法只會傳送應用程式初次載入時所需的 JavaScript,進而縮短載入時間。

程式碼分割技術

程式碼分割可在兩個層級進行:元件層級路徑層級

  • 在元件層級的程式碼分割中,您可以將元件移至專屬的 JavaScript 區塊,並在需要時延遲載入元件。
  • 在路徑層級程式碼分割中,您會將每個路徑的功能封裝成一個獨立區塊。使用者瀏覽您的應用程式時,會擷取與個別路徑相關聯的區塊,並在需要時取得相關功能。

本文著重說明如何設定 Angular 的路徑層級分割作業。

應用程式範例

開始學習如何使用 Angular 中的路徑層級程式碼分割功能之前,我們先來看看範例應用程式:

查看應用程式模組的實作方式。在 AppModule 中,有兩個路線定義:與 HomeComponent 相關聯的預設路徑和與 NyanComponent 相關聯的 nyan 路線:

@NgModule({
  ...
  imports: [
    BrowserModule,
    RouterModule.forRoot([
      {
        path: '',
        component: HomeComponent,
        pathMatch: 'full'
      },
      {
        path: 'nyan',
        component: NyanComponent
      }
    ])
  ],
  ...
})
export class AppModule {}

路徑層級程式碼分割

如要設定程式碼分割功能,必須重構 nyan Eager 路徑。

Angular CLI 8.1.0 版可以使用這個指令完成所有操作:

ng g module nyan --module app --route nyan

這會產生: - 名為「NyanModule」的新轉送模組 - AppModule 中名為 nyan 的路徑,會動態載入 NyanModule - NyanModule 中的預設路徑 - 名為 NyanComponent 的元件,會在使用者到達預設路徑時算繪

讓我們手動逐步完成這些步驟,以便您進一步瞭解如何使用 Angular 實作程式碼分割功能!

當使用者前往 nyan 路徑時,路由器會在路由器插座上轉譯 NyanComponent

如要在 Angular 中使用路徑層級程式碼分割功能,請設定路徑宣告的 loadChildren 屬性,然後與動態匯入功能結合:

{
  path: 'nyan',
  loadChildren: () => import('./nyan/nyan.module').then(m => m.NyanModule)
}

這個路徑與熱食路徑有以下兩個主要差異:

  1. 您設定的是 loadChildren,而非 component。使用路徑層級程式碼分割功能時,您必須指向動態載入的模組,而非元件。
  2. loadChildren 中,當承諾結果解決後,會傳回 NyanModule,而不是指向 NyanComponent

上述程式碼片段指定當使用者前往 nyan 時,Angular 應從 nyan 目錄動態載入 nyan.module,並轉譯與模組中宣告預設路徑相關聯的元件。

您可以使用這個宣告,將預設路徑與元件建立關聯:

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 {}

當使用者前往 https://example.com/nyan 時,此程式碼會算繪 NyanComponent

如要檢查 Angular 路由器是否在本機環境中延遲下載 nyan.module

  1. 按下 Control+Shift+J 鍵 (或在 Mac 上為 Command+Option+J 鍵) 開啟開發人員工具。
  2. 按一下 [網路] 分頁標籤。

  3. 在範例應用程式中,按一下「NYAN」NYAN

  4. 請注意,nyan-nyan-module.js 檔案會顯示在「Network」分頁中。

使用路徑層級程式碼分割功能延遲載入 JavaScript 套件

前往 GitHub 查看這個範例。

顯示旋轉圖示

目前,當使用者按一下「NYAN」NYAN按鈕時,應用程式並未指示它在背景載入 JavaScript。如要在載入指令碼時向使用者提供意見回饋,可以加入旋轉圖示。

方法是先在 app.component.htmlrouter-outlet 元素中新增指標標記:

<router-outlet>
  <span class="loader" *ngIf="loading"></span>
</router-outlet>

然後新增 AppComponent 類別來處理轉送事件。此類別會在聽到 RouteConfigLoadStart 事件時將 loading 標記設為 true,並在聽到 RouteConfigLoadEnd 事件時將標記設為 false

@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;
        }
      }
    );
  }
}

在下方範例中,我們引進了人工 500 毫秒的延遲時間,方便您瞭解旋轉圖示的實際運作情形。

結論

您可以套用路徑層級的程式碼分割作業,縮減 Angular 應用程式的套件大小:

  1. 使用 Angular CLI 延遲載入模組產生器,自動偵察動態載入的路徑。
  2. 在使用者前往延遲路徑時顯示載入指標,表示有正在進行的動作。