この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
どうも!大阪オフィスの西村祐二です。
SPAでサイトを作っていると機能追加などでどんどんコンポーネントが肥大化してしまい表示までに時間がかかることがあると思います。
AngularではLazyloadモジュールという遅延読み込みを行うことができる機能が提供されており、必要なファイルだけ読み込むように設定することができます。
具体例をあげると
サイトにアクセスした際にログイン画面が表示されるサイトがあるとします。 LazyLoadモジュールを使いログイン画面にアクセスしたときはログインに関するデータだけ読み込み、他のデータはログイン後に読み込むといったことが実現できます。
これにより、最初に読み込むコンテンツの量を減らして、初期ページの読み込みの高速化が期待できます。
やってみる
環境
Angular CLI: 7.0.2
Node: 8.11.3
OS: darwin x64
Angular: 7.0.0
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.10.2
@angular-devkit/build-angular 0.10.2
@angular-devkit/build-optimizer 0.10.2
@angular-devkit/build-webpack 0.10.2
@angular-devkit/core 7.0.2
@angular-devkit/schematics 7.0.2
@angular/cli 7.0.2
@ngtools/webpack 7.0.2
@schematics/angular 7.0.2
@schematics/update 0.10.2
rxjs 6.3.3
typescript 3.1.3
webpack 4.19.1
プロジェクト作成
$ ng new lazyload --routing
$ cd lazyload
コンポーネント作成
$ ng g c home
モジュール作成
遅延読み込みをさせるためにモジュールを作成します。名前は好きな名前で大丈夫です。
--routing
を忘れずに。
これをつけることでforChild
となる親ファイルと紐づくルーティングファイルを自動的に作成してくれます。
$ ng g module Lazy --routing
遅延読み込みさせたいコンポーネントを作成
$ ng g c lazy/lazy-page --module Lazy
作成が完了すると追加したlazy.module.ts
にlazy-pageコンポーネントが追記されているかと思います。
lazy.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LazyRoutingModule } from './lazy-routing.module';
import { LazyPageComponent } from '../lazy/lazy-page/lazy-page.component';
@NgModule({
imports: [
CommonModule,
LazyRoutingModule
],
declarations: [LazyPageComponent]
})
export class LazyModule { }
ルーティング
いつもの通りにルーティング設定します。
lazy-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LazyPageComponent } from './lazy-page/lazy-page.component';
const routes: Routes = [
{
path: '',
component: LazyPageComponent
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class LazyRoutingModule {}
loadChildren
としてモジュールを指定することによって遅延読み込みをしてくれるようになります。
似たような構文でchildren
がありますが、こちらは遅延読み込みにならないので注意ください。
app-routing.module.ts
import { HomeComponent } from './home/home.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [
{
path: '',
component: HomeComponent
},
{
path: 'lazy',
loadChildren: './lazy/lazy.module#LazyModule'
},
{
path: '**',
redirectTo: ''
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
画面
挙動がわかりやすいようにボタン配置し、「LazyPage」ボタンをクリックされたら、遅延読み込みに指定したファイルが読み込まれるようにしています。
つまり、Homeコンポーネントしかはじめは読み込まれていないということになります。
src/app/app.component.html
<h1>
{{title}}
</h1>
<button routerLink="/lazy">LazyPage</button>
<button routerLink="">Home</button>
<router-outlet></router-outlet>
下記のような画面になっているかと思います。
イメージ図
遅延読み込みのイメージとしては下記の図のようにボタンがクリックされたら、LazyPageコンポーネントが読み込まれるイメージをしていただければよいかと思います。
それまでは読み込まれないので、最初に読み込むコンテンツの量を減らすことができたということになります。
動作確認
ChromeのDevツールを使って確認します。
- ボタンクリック前
- ボタンクリック後
プロダクションビルドしたときの出力ファイル
LazyLoadモジュールを使うときのちょっとした注意点としては、遅延読み込みするためにファイル分割する必要があり、ビルドした後に出力されるファイル数が遅延読み込みする分増えるのでご注意ください。
- 遅延読み込みなし
- 遅延読み込みあり
さいごに
いかがだったでしょうか。
AngularのLazyLoadを使い、最初に読み込むコンテンツの量を減らす方法を紹介しました。
LazyLoadを使うことによって簡単に遅延読み込みをすることができ便利なのでどんどん使っていきたいと思います。
誰かの参考になれば幸いです。