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

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

本文說明如何在 Angular 應用程式中設定路徑層級程式碼分割,這可縮減 JavaScript 組合大小,並大幅改善 Time to Interactive。

您可以在 GitHub 找到本文中的程式碼範例。積極轉送範例位於積極分支版本。路徑層級程式碼分割範例位於 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 積極路徑。

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 中,Promise 解析後,您會傳回 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 檔案。

使用路徑層級程式碼分割,延遲載入 JavaScript 組合

在 GitHub 上查看這個範例。

顯示旋轉圖示

目前,當使用者點選「NYAN」NYAN按鈕時,應用程式不會指出正在背景載入 JavaScript。如要在載入指令碼時向使用者提供意見回饋,建議您新增旋轉圖示。

首先,請在 app.component.html 的 router-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. 在使用者前往延遲路徑時,加入載入指標,表示有動作正在進行。