Angular でのルート プリロード戦略

ルートをプリロードして、ユーザーの応答をナビゲーションです。

ルートレベルでのコード分割を使用すると、最初に必要のないルートに関連付けられた JavaScript を遅延させることで、アプリケーションの初期読み込み時間を短縮できます。このようにして、Angular ルーターは、ユーザーが特定のルートに移動するまで待機してから、関連する JavaScript をダウンロードするためのネットワーク リクエストをトリガーします。

この手法は最初のページ読み込みには適していますが、ユーザーのアクセスによっては操作が遅くなることがありますネットワークのレイテンシと帯域幅です。この問題に対処する方法の一つとして、ルートのプリロードがあります。プリロードを使用すると、ユーザーが特定のルートにいるときに、次に必要になる可能性が高いルートに関連付けられている JavaScript をダウンロードしてキャッシュに保存できます。Angular ルーターにはこの機能が最初から組み込まれています。

この投稿では、Angular の JavaScript プリロードを利用して、ルートレベルのコード分割を使用する際にナビゲーションを高速化する方法について説明します。

Angular でのルートのプリロード戦略

Angular ルーターには、preloadingStrategy という構成プロパティが用意されています。このプロパティは、遅延読み込みされる Angular モジュールのプリロードと処理のロジックを定義します。次の 2 つの戦略を取り上げます。

  • PreloadAllModules: 名前のとおり、遅延読み込みのすべてのルートをプリロードします。
  • QuicklinkStrategy: 現在のページのリンクに関連付けられているルートのみをプリロードします。

この投稿の残りの部分では、Angular アプリのサンプルについて説明します。ソースコードは GitHub にあります。

PreloadAllModules 戦略の使用

サンプルアプリには、遅延読み込みのルートがいくつかあります。Angular に組み込まれている PreloadAllModules 戦略を使用してこれらすべてをプリロードするには、ルーター構成の preloadingStrategy プロパティの値として指定します。

import { RouterModule, PreloadAllModules } from '@angular/router';
// …

RouterModule.forRoot([
  …
], {
  preloadingStrategy: PreloadAllModules
})
// …

次に、アプリケーションを提供し、Chrome DevTools の [ネットワーク] パネルを確認します。

  1. `Ctrl+Shift+J` キー(Mac の場合は `Command+Option+J`)を押して、DevTools を開きます。
  2. [ネットワーク] タブをクリックします。

アプリケーションを開いたときに、ルーターが nyan-nyan-module.jsabout-about-module.js をバックグラウンドでダウンロードしていることがわかります。

<ph type="x-smartling-placeholder">
</ph>
PreloadAllModules 戦略の実例

そのルーターはモジュールをルート宣言を使用して、プリロードされたモジュールに関連付けられた URL に移動したときに、即座に遷移するようにできます。

PreloadAllModules はさまざまな場面で役立ちます。ただし、数十個のモジュールがある場合、その積極的なプリロードはネットワーク使用量を大幅に増加させる可能性があります。また、ルーターはプリロードされたすべてのモジュールにルートを登録する必要があるため、UI スレッドで集中的な計算処理が引き起こされ、ユーザー エクスペリエンスの低下につながる可能性があります。

大規模なアプリの場合、quicklink ライブラリのほうが適しています。IntersectionObserver API を使用して、ページに現在表示されているリンクに関連付けられているモジュールのみをプリロードします。

ngx-quicklink パッケージを使用すると、Angular アプリにクイックリンクを追加できます。まず、npm からパッケージをインストールします。

npm install --save ngx-quicklink

プロジェクトで使用可能になったら、ルーターの preloadingStrategy を指定して QuicklinkModule をインポートして、QuicklinkStrategy を使用できます。

import {QuicklinkStrategy, QuicklinkModule} from 'ngx-quicklink';
…

@NgModule({
  …
  imports: [
    …
    QuicklinkModule,
    RouterModule.forRoot([…], {
      preloadingStrategy: QuicklinkStrategy
    })
  ],
  …
})
export class AppModule {}

アプリを再度開くと、ページ中央のボタンにルーターへのリンクがあるため、ルーターは nyan-nyan-module.js のみをプリロードすることがわかります。サイド ナビゲーションを開くと、ルーターに「About」がプリロードされているのがわかります。route:

<ph type="x-smartling-placeholder">
</ph>
クイックリンクのプリロード方法のデモ

上の例は基本的なアプリでは機能しますが、アプリに遅延読み込みモジュールが複数ある場合は、QuicklinkModule を共有モジュールにインポートしてからエクスポートした後、遅延読み込みモジュールにインポートする必要があります。

まず、QuicklinkModulengx-quicklink から共有モジュールにインポートしてエクスポートします。

import { QuicklinkModule } from 'ngx-quicklink';
…

@NgModule({
  …
  imports: [
    QuicklinkModule
  ],
  exports: [
    QuicklinkModule
  ],
  …
})
export class SharedModule {}

次に、遅延読み込みされるすべてのモジュールに SharedModule をインポートします。

import { SharedModule } from '@app/shared/shared.module';
…

@NgModule({
  …
  imports: [
      SharedModule
  ],
  …
});

これで、遅延読み込みモジュールで Quicklinks を使用できるようになりました。

基本的なプリロードの枠を超える

クイックリンクで選択的にプリロードすると、移動速度が大幅に向上しますが、予測プリロード(Guess.js で実装)を使用することで、プリロード戦略をより効率的に行うことができます。Guess.js は、Google アナリティクスや他のアナリティクス プロバイダのレポートを分析することで、ユーザーの操作の流れを予測し、次に必要になると思われる JavaScript チャンクのみをプリロードできます。

Angular で Guess.js を使用する方法については、Guess.js サイトのこちらのページをご覧ください。

まとめ

ルートレベルでコード分割を使用するときにナビゲーションを高速化するには:

  1. アプリケーションのサイズに応じて適切なプリロード戦略を選択します。 <ph type="x-smartling-placeholder">
      </ph>
    • モジュールが少ないアプリケーションでは、Angular の組み込み PreloadAllModules 戦略を使用できます。
    • モジュールが多数あるアプリケーションでは、Angular のクイックリンクなどのカスタム プリロード戦略や、Guess.js で実装された予測プリロードを使用する必要があります。
  2. Angular ルーターの preloadStrategy プロパティを設定して、プリロード戦略を構成します。