ユーザーのナビゲーションを高速化するために、ルートを事前にプリロードします。
ルートレベルのコード分割を使用すると、最初に必要のないルートに関連付けられた JavaScript を遅らせることで、アプリケーションの最初の読み込み時間を短縮できます。これにより、Angular ルーターは、ユーザーが特定のルートに移動するまで待機してから、関連する JavaScript をダウンロードするためのネットワーク リクエストをトリガーします。
この手法はページの初回読み込みには適していますが、ユーザーのネットワーク レイテンシと帯域幅によっては、ナビゲーションの速度が低下する可能性があります。この問題に対処する 1 つの方法は、ルートのプリロードです。プリロードを使用すると、ユーザーが特定のルートにいるときに、次に必要となる可能性が高いルートに関連付けられた 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 の [Network] パネルを確認します。
- Ctrl+Shift+J(Mac の場合は Command+Option+J)キーを押して DevTools を開きます。
- [ネットワーク] タブをクリックします。
アプリを開いたときに、ルーターで 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
のみをプリロードします。サイドナビゲーションを開くと、ルーターで「概要」ルートがプリロードされます。
複数の遅延読み込みモジュールで 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
プロパティを設定して、プリロード戦略を構成します。