ルートモジュールで他モジュール機能を使用する方法【遅延ロード編】

どうもこんにちはコウヘイです。
本シリーズは、Angularについて完全初心者の私がAngularをある程度使えるようになるまで頑張るをテーマに日々の作業ログを記録する内容になります。
以下のような疑問を持ちました。
・モジュールの遅延ロードの方法を知りたい。
今回はこういった疑問に答えます。
著者情報
この記事を書いている僕ですが、Javaをメインにバックサイド開発を7年ほど経験しています。
最近フロントサイドにAngular、バックサイドにSpringBootを使用したSPA(シングルページアプリケーション)を作成する案件で働き始めたので、Angular学習を開始しました。
こんな僕が解説していきます。
ルートモジュールで他モジュール機能を使用する方法【遅延ロード編】
モジュールの遅延ロードの解説は以下です。
追加したモジュールのコンテンツにアクセスがあったタイミングで、そのモジュールのコンテンツを読み込む方法
※Angularで最初に読み込むコンテンツに、追加したモジュールが含まれない
さらに、遅延ロードを用いるメリットは以下になります。
初期ページ読み込み時に必要ではないコンテンツをロードしないので、初期バンドルサイズを小さくでき、初期ロード時間を短縮できる。つまり、パフォーマンスの向上が期待される。
大規模開発になればなるほど、遅延ロードを使用するメリットがありそうです。
実際に私が現在稼働している現場でもモジュールの遅延ロードを使用しています。
Angularを使用する場合は必須の知識になってくると思うので、本記事でモジュールの遅延ロードについてまとめたいと思います。
ちなみに、遅延ロードの反対の即時ロードについては、以下の記事でよくまとまっています。詳しく知りたい方は参考にしてみてください。
≫ ルートモジュールで他モジュール機能を使用する方法【即時ロード編】
それでは本題、手順は以下になります。
手順①:ルートモジュールのルーティングモジュール作成【遅延ロード】
手順②:Userモジュールのルーティングモジュール作成
手順③:ルートコンポーネントの変更
手順④:動作確認
順に説明します。
手順①:ルートモジュールのルーティングモジュール作成【遅延ロード】
モジュールを遅延ロードさせるためには、以下のようにルートモジュールで使用するルーティングモジュールを作成します。
※今回は新規で作成したUserモジュールを遅延ロードさせます。
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; const routes: Routes = [ { path: 'user', loadChildren: () => import('./user/user.module').then(m => m.UserModule) ・・・① } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
変更点の説明は以下。
① 遅延ロードをさせるためには、loadChildrenを使用します。loadChildrenには動的インポート用のimport(‘…’)関数を指定します。このことにより、指定したURLにアクセスがあったタイミングで動的にインポートされるようになります。
手順②:Userモジュールのルーティングモジュール作成
以下のUserモジュールで使用するルーティングモジュールを作成します。
※変更点は①~②です。
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { UserInfoComponent } from './user-info/user-info.component'; import { UserComponent } from './user.component'; const routes: Routes = [ {path: '', component: UserComponent}, ・・・① {path: 'userinfo', component: UserInfoComponent} ・・・② ]; @NgModule({ imports: [RouterModule.forChild(routes)], ・・・③ exports: [RouterModule] }) export class UserRoutingModule { }
各変更点の説明は以下。
① ルーティング情報にUserコンポーネントを追加してます。
② ルーティング情報にUserInfoコンポーネントを追加してます。
③ ルートモジュール以外のモジュールのルーティングモジュールではforChildを使用します。※ルートモジュールではforRootを使用。
手順③:ルートコンポーネントの変更
今回はルートコンポーネントでUserコンポーネントを表示するために、「user.component.html」を以下に書き換えます。
<router-outlet></router-outlet> ・・・①
変更点の説明は以下。
① 「router-outlet」タグを記述すると、アクセスがあったコンポーネントが表示されるようになります。
手順④:動作確認
最後に遅延モジュールのコンポーネントにアクセスして動作確認をしてみます。
「http://localhost:4200/user」にアクセスした場合は以下。

「http://localhost:4200/user/userinfo」にアクセスした場合は以下。

無事にモジュールを遅延ロードすることができました!
応用編:遅延ロードモジュールをプリロードする方法
モジュールのプリロードについての説明については以下です。
・初期ページ読み込み後にバックグラウンドで遅延モジュールのコンテンツを事前にロードする方法。プリロードを用いることで、遅延モジュール読み込み時間を短縮でき、UX向上が見込める。
以下の画像で、プリロードする前は初期ページ読み込み時には遅延ロードモジュールのコンテンツは読み込まれていないことがわかります。

遅延モジュールのコンテンツにアクセスがあったタイミングでコンテンツを読み込むので、コンテンツ量が多いと読み込み時間が長くなってしまいます。
そういった場合にプリロードを導入すると、UXが改善されます。
それでは実際に遅延ロードモジュールをプリロードする手順を解説していきます。
手順は以下。
手順①:ルートモジュールのルーティングモジュールの変更
手順②:動作確認
順に説明します。
手順①:ルートモジュールのルーティングモジュールの変更
プリロードするためには、以下のようにルートモジュールで使用するルーティングモジュールを変更します。
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { PreloadAllModules } from '@angular/router'; const routes: Routes = [ { path: 'user', loadChildren: () => import('./user/user.module').then(m => m.UserModule) } ]; @NgModule({ imports: [ RouterModule.forRoot( routes, { preloadingStrategy: PreloadAllModules ・・・① } ) ], exports: [RouterModule] }) export class AppRoutingModule { }
各変更点の説明は以下。
① 遅延ロードモジュールをプリロードするには、forRootのpreloadingStrategyにPreloadAllModulesを指定します。
はい、おまじないだと思っていいです。
手順②:動作確認
遅延ロードモジュールをプリロードするように変更した場合の動作確認をしてみます。

無事に初期ページで遅延ロードモジュールをプリロードすることができました!
遅延ロードモジュールとサービスプロバイダの関係
最後に軽く遅延モジュールとサービスプロバイダの関係について書いおきたいと思います。
公式サイトをざっとまとめると以下になります。
- 遅延ロードモジュールでサービスプロバイダのスコープを制限できる
- 遅延ロードモジュールではルートモジュールとは別のインスタンスのサービスプロバイダを使用する
ここに関しては、別の機会に詳しく書きたいと思います。少々お待ちください。
というわけで今回は以上です。
Angularについて、少しでも詳しくなれたなら幸いです。
私自身も発展途上なので一緒に学んでいきましょう!
おすすめ記事:無料あり:Angular学習におすすめの本【AngularJSとの違いに注意】
