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

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

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

您可以在 GitHub 上找到本文的程式碼範例。您可以在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 急就路徑。

只要使用以下指令,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

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

使用路徑層級程式碼分割功能,延後載入 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. 在使用者前往延遲路徑時新增載入指標,以顯示正在進行的動作。