Angularの3種類のLoad方法について
最近Angularの勉強をやっているのでメモ半分でアウトプットしようと思います!今回はAngularのWebページのロード方法についての解説です.
通常のLoad
まずは通常のロードを使用した例をお見せしようと思います.このパターンは全てのページのモジュールを初回アクセス時に取得します.コードは以下にあげています. https://github.com/Yoshiaki-Harada/angular-lazy-load
今回はHOMEというページとSAMPLEというページを用意しました.SAMPLEというページにはchild1とchild2コンポーネントが埋め込まれています.HOMEからSAMPLEに飛べるように作成しています.
HOME
<h3> HOME </h3> <br> <ul> <li><a [routerLink]="[ '/sample' ]">Sample</a></li> </ul>
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home.component.scss'] }) export class HomeComponent implements OnInit { constructor() { } ngOnInit(): void { } }
SAMPLE
<h3>SAMPLE PAGE</h3> <p> This is Sample Page </p> <app-child1></app-child1> <app-child2></app-child2>
CHILD
<p>child1 works!</p>
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-child1', templateUrl: './child1.component.html', styleUrls: ['./child1.component.scss'] }) export class Child1Component implements OnInit { constructor() { } ngOnInit(): void { } }
child2はchild1とほぼ同じなので割愛します.
Routing
これらのHOMEページとSAMPLEページをRoutingに登録します.
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { SampleComponent } from './sample/sample.component'; const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'sample', component: SampleComponent }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
プロジェクトを作成するときにrouteモジュールをimportするにyesと答えた場合app-routing.module
というファイルは自動で生成されます.このroutesに自分が作成したコンポーネントを登録します.
またこのrouteに登録したページを表示するにはapp.component.html
で以下のように<router-outlet></router-outlet>
を登録する必要があります.
<router-outlet></router-outlet>
アクセス結果
アプリケーションをたて,接続してみるとmain.js
が22.5kBとなっています.
次にSampleページをクリックします.
特に追加でmoduleがロードされている様子はみられません.このように通常では全て最初にロードされます.
Lazy Load
次にそのページにアクセスされたタイミングはじめてロードするようにSampleページを作った場合を解説します.
Lazy Loadへの対応
lazy loadを実現するにはまずsample.module.ts
を作成します.こちら先ほどのsample.component.ts
と同階層に作成します.Child1Componet,Child2Componetもここで読み込むようにします.
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SampleRoutingModule } from './sample-routing.module'; import { SampleComponent } from './sample.component'; import { Child1Component } from './child1/child1.component'; import { Child2Component } from './child2/child2.component'; @NgModule({ declarations: [SampleComponent, Child1Component, Child2Component], imports: [ CommonModule, SampleRoutingModule ] }) export class SampleModule { }
次にsample-routing.module
を作成します.
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { SampleComponent } from './sample.component'; const routes: Routes = [{ path: '', component: SampleComponent }]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class SampleRoutingModule { }
次にapp-routing.module
を以下のように変更します.
const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'sample', loadChildren: () => import('./sample/sample.module').then(m => m.SampleModule) } ];
このloadChiledren
の部分がポイントで,pathのsampleにアクセスされてはじめてロードするということを表しています.
このコードは以下のコマンドを打つことで自動で生成することもできます.
ng g module sample --module app --route sample
アクセス結果
実際にアクセスしてみます.
main.js
のサイズが22.5kBより大分小さくなっていることが確認できます.このときSampleモジュールはまだロードされていないからです.
次にSampleページに飛んでみます.
sample-sample-module.js
がこのタイミングでロードされたことがわかります.このように遅延ロードを活用すると,最初のページに必要なモジュールを減らし,初めのページを表示する速度を早めることができます.
Pre Load
Pre loadとは初回のページはLazy Load通りに表示されるのですが,後でロードしてくるモジュールを,その後すぐにloadするというロード方法です.Lazy Loadでは訪れてはじめてloadされますが,Pre Loadは裏で先に準備しておくという感じです.
Pre Loadへの対応
app-routing.module.ts
の
RouterModule.forRoot
にオプションとしてpreloadingStrategy:PreloadAllModules
を渡すだけPre Loadは実現できます.preloadingStrategy
には他にもQuicklinkStrategy
などがあるそうです.
const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'sample', loadChildren: () => import('./sample/sample.module').then(m => m.SampleModule) } ]; @NgModule({ imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })], exports: [RouterModule] }) export class AppRoutingModule { }
アクセス結果
このようにmain.js
がロードされた後でsample-sample-module.js
がロードされていることがわかります.
裏で初回ページは軽くしたいが,裏でロードしておいてして欲しい!って時にはこのPre Loadを使うのがいいと思います.
まとめ
Angularの3つのロード方法について解説しました.angular cliを使えば簡単にLazy Loadを使ったmoduleを作成できるので複数のページがあるアプリケーションを作りたい方はぜひ使うべきだなと感じました!!