ユーザーのナビゲーションを高速化するため、ルートを事前にプリロードしておきます。
ルートレベルのコード分割を使用すると、当初必要のないルートに関連付けられた JavaScript を遅延させることで、アプリケーションの初期読み込み時間を短縮できます。このように、Angular ルーターは、ユーザーが特定のルートに移動するまで待機してから、関連する JavaScript をダウンロードするネットワーク リクエストをトリガーします。
この手法は最初のページ読み込みには適していますが、ユーザーのネットワークのレイテンシや帯域幅によっては、ナビゲーションが遅くなることがあります。この問題に対処する方法の一つが、ルートのプリロードです。プリロードを使用すると、ユーザーが特定の経路にいるときに、次に必要になる可能性が高い経路に関連付けられた JavaScript をダウンロードしてキャッシュに保存できます。Angular ルーターは、この機能をすぐに利用できます。
この投稿では、Angular の JavaScript プリロードを利用して、ルートレベルのコード分割を使用する場合にナビゲーションを高速化する方法について説明します。
Angular でのルート プリロード戦略
Angular ルーターには、遅延読み込みされた Angular モジュールのプリロードと処理のロジックを定義する preloadingStrategy
という構成プロパティがあります。ここでは、次の 2 つの戦略について説明します。
PreloadAllModules
: その名が示すように、遅延読み込みされるすべてのルートをプリロードします。QuicklinkStrategy
: 現在のページ上のリンクに関連付けられているルートのみをプリロードします。
この投稿の残りの部分では Angular アプリのサンプルを参照します。ソースコードは GitHub にあります。
PreloadAllModules
戦略の使用
サンプルアプリには、遅延読み込みされるルートがいくつかあります。Angular に組み込まれている PreloadAllModules
戦略を使用してこれらすべてをプリロードするには、ルーター構成で preloadingStrategy
プロパティの値として指定します。
import { RouterModule, PreloadAllModules } from '@angular/router';
// …
RouterModule.forRoot([
…
], {
preloadingStrategy: PreloadAllModules
})
// …
アプリケーションを提供し、Chrome DevTools の [Network] パネルを確認します。
- Ctrl+Shift+J キー(Mac の場合は Command+Option+J キー)を押して DevTools を開きます。
- [Network] タブをクリックします。
アプリを開くと、ルーターがバックグラウンドで nyan-nyan-module.js
と about-about-module.js
をダウンロードしているはずです。
また、ルーターはモジュールのルート宣言も登録しているため、プリロードされたモジュールのいずれかに関連付けられた URL に移動すると、即座に移行が行われます。
Quicklink プリロード戦略の使用
PreloadAllModules
はさまざまな場面で役立ちます。ただし、数十個のモジュールがある場合、その積極的なプリロードにより、ネットワーク使用量が大幅に増加する可能性があります。また、ルーターはプリロードされたすべてのモジュールでルートを登録する必要があるため、UI スレッドで負荷の高い計算が発生し、ユーザー エクスペリエンスが低下する可能性があります。
大規模なアプリでは、quicklink ライブラリの方が適切な戦略になります。IntersectionObserver API を使用して、ページに現在表示されているリンクに関連付けられているモジュールのみをプリロードします。
Angular アプリにクイックリンクを追加するには、ngx-quicklink パッケージを使用します。まず、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」ルートがプリロードされていることがわかります。
複数の遅延読み込みモジュールに Quicklink プリロード戦略を使用する
上記の例は基本的なアプリでは機能しますが、アプリに遅延読み込みされるモジュールが複数ある場合は、QuicklinkModule
を共有モジュールにインポートし、それをエクスポートしてから、共有モジュールを遅延読み込みモジュールにインポートする必要があります。
まず、ngx-quicklink
から共有モジュールに QuicklinkModule
をインポートしてエクスポートします。
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 のサイトのページをご覧ください。
まとめ
ルートレベルのコード分割を使用する場合にナビゲーションを高速化するには:
- アプリケーションのサイズに応じて、適切なプリロード戦略を選択します。
- モジュールが少ないアプリでは、Angular に組み込まれた
PreloadAllModules
戦略を使用できます。 - 多くのモジュールを含むアプリケーションでは、Angular のクイックリンクなどのカスタム プリロード戦略や、Guess.js に実装されている予測プリロードを使用する必要があります。
- モジュールが少ないアプリでは、Angular に組み込まれた
- Angular ルーターの
preloadStrategy
プロパティを設定して、プリロード戦略を構成します。