angular-cliでAngular2モジュールの遅延ロード(lazy load）を試してみる


通常のWebアプリケーションのフロントエンド開発を行う場合、一般ユーザーがログイン等を行わず利用する画面と、会員ユーザーがログインして使う画面や管理者画面があります。

前者は初めて訪れるユーザー向けのページであることが多く、ページが表示されるまでの時間が気になることが多いと思います。
そこで、ログインして利用するような画面の部分を必要なタイミングで遅延ロードして画面表示するようにすることで、Webアプリケーションの初期表示時にダウンロードされるjsファイルのサイズを小さくする方法があります。

今回は、以下のサイトで紹介されていたangular-cliでAngular2モジュールの遅延ロード(lazy load）を行う方法を実際に試してみます。


[参考：Lazy-loading content with angular-cli](https://keathmilligan.net/lazy-loading-content-with-angular-cli/)

#今回の実行環境
```
angular-cli: 1.0.0-beta.28.3
node: 6.10.3
os: macOS Sierra
```
#アプリの作成
`angular-cli-lazyload`という名前のプロジェクトを作成します。`--routing true`オプションでルーティング設定付きにします。
> ng new --routing true angular-cli-lazyload


初期表示コンポーネントとして`Home`を作成します。このコンポーネントは遅延ロードしない普通のやつです。
> ng g component Home

#遅延ロードするモジュールを追加
`Lazy`という名前で遅延ロードするモジュールを生成します。名前はなんでもいいと思います。`--routing true`オプションでルーティング設定付きにします。
実行すると、勝手に`app`フォルダ内に`Lazy`というフォルダが作成され、その中にlazy.componentが生成されました。
> ng g module --routing true Lazy

遅延ロードされるLazyモジュールが表示するコンポーネントを`LazyPage`という名前で生成します。
> ng g component lazy/LazyPage

`src/app/lazy/lazy-routing.module.ts`に生成された`LazyPage`の設定を追加します。

```Javascript:src/app/lazy/lazy-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import {LazyComponent} from './lazy.component';
import {LazyPageComponent} from './lazy-page/lazy-page.component';

const routes: Routes = [{
  path: '',
  component: LazyComponent,
  children: [
    {
      path: 'lazypage',
      component: LazyPageComponent
    }
  ]
}];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
  providers: []
})
export class LazyRoutingModule { }
```

`src/app/lazy/lazy.component.html`に`router-outlet`設定を追加。

```HTML:src/app/lazy/lazy.component.html
<h2>Lazy Module</h2>

<router-outlet></router-outlet>
```

#アプリケーションのルーティング設定を修正
`src/app/app-routing.module.ts`に、`lazy`以下のURLにアクセスした際に`LazyModule`を遅延ロードする設定を追加

```js:src/app/app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import {HomeComponent} from './home/home.component';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'lazy', loadChildren: './lazy/lazy.module#LazyModule' },
  { path: '**', redirectTo: '' }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: []
})
export class AppRoutingModule { }

```

`src/app/app.component.html`にナビゲーション設定を追加します。

```html:src/app/app.component.html
<h1>
  {{title}}
</h1>

<p>Navigation:
  <a [routerLink]="['/']">Home</a>
  <a [routerLink]="['lazy/lazypage']">Lazy Page</a>
</p>

<h3>Current Route:</h3>
<router-outlet></router-outlet>

```

#試してみる
アプリケーションをコンパイルして起動する。
> ng serve

chromeとかのブラウザでディベロッパーツール等を起動してNetworkを表示した状態で`http://localhost:4200`にアクセスしてみる
![スクリーンショット 2017-05-20 13.13.16.png](https://qiita-image-store.s3.amazonaws.com/0/9784/b7049123-e6d8-a15d-e54d-7cb3cecc6807.png "スクリーンショット 2017-05-20 13.13.16.png")

`Lazy Page`のリンクをクリックして画面遷移すると、`0.chunk.js`が遅延ロードされているのが分かります。
![スクリーンショット 2017-05-20 13.13.38.png](https://qiita-image-store.s3.amazonaws.com/0/9784/8f2b18c2-2576-ad27-b528-5805c6685692.png "スクリーンショット 2017-05-20 13.13.38.png")

すごい！簡単にできました〜。