Angular8でPWAを導入しIvyのパフォーマンスを検証

# Angular8でPWAを導入しIvyのパフォーマンスを検証

現在(11/19, 2019)、Angularのバージョン*8.2.14*。これでPWAアプリを作るための新規プロジェクト作成手順を。

※なおPWAとService Workerのナレッジと動作確認方法はこの本を参考にした。:arrow_down:
<a target="_blank"  href="https://www.amazon.co.jp/gp/product/4822254534/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4822254534&linkCode=as2&tag=kokkahasan-22&linkId=da489dc6f9c827eab993d1ea7d086869"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&MarketPlace=JP&ASIN=4822254534&ServiceVersion=20070822&ID=AsinImage&WS=1&Format=_SL160_&tag=kokkahasan-22" ></a><img src="//ir-jp.amazon-adsystem.com/e/ir?t=kokkahasan-22&l=am2&o=9&a=4822254534" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
<a target="_blank" href="https://www.amazon.co.jp/gp/product/4822254534/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4822254534&linkCode=as2&tag=kokkahasan-22&linkId=942b842a41cc4a1696a75d9b81ec8862">AngularによるモダンWeb開発 基礎編 第2版</a><img src="//ir-jp.amazon-adsystem.com/e/ir?t=kokkahasan-22&l=am2&o=9&a=4822254534" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />



### 前提確認：必要なもの

サーバー側に、

1. https通信
2. HTTP/2プロトコル対応
3. HTTP/2圧縮

が必要だがFirebase Hostingで問題ない。
「本日（*2016年10月5日）は Firebase Hosting で HTTP/2 が利用できるようになった…略…、***Firebase Hosting で HTTP/2 を利用するために必要なことは何もありません。***」[[Firebase Hosting が HTTP/2 に対応](https://developers-jp.googleblog.com/2016/10/firebase-hosting-http2.html)]

######ローカルで試す場合、
-- HTTPSいらない --
「例外として開発時に利用する`http://localhost`からはhttp通信でServer Workerを利用可能」


<br />

node, npm はインストール済み。

```bash
$ node --version
v10.15.3
$ nmp --version
6.4.1
```

<br />

### Angularプロジェクトを作成。

- 下記コマンドでAngular CLIをインストール

```bash
$ npm install -g @angular/cli@latest
```

- プロジェクトフォルダに移動し新しいプロジェクトを作成

```bash
$ ng new my-app --routing --style=scss
```


最後に、` Successfully initialized git.`と出力されていれば成功。

<br />

- プロジェクトができたら、プロジェクトフォルダに移動。

```cmd
$ cd my-app
```

- `ng --version`でバージョンを確認。

```bash
$ ng --version
     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 7.1.4
Node: 10.15.3
OS: win32 x64
Angular: 7.1.4
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.11.4
@angular-devkit/build-angular     0.11.4
@angular-devkit/build-optimizer   0.11.4
@angular-devkit/build-webpack     0.11.4
@angular-devkit/core              7.1.4
@angular-devkit/schematics        7.1.4
@ngtools/webpack                  7.1.4
@schematics/angular               7.1.4
@schematics/update                0.11.4
rxjs                              6.3.3
typescript                        3.1.6
webpack                           4.23.1
```

ア、アレ？バージョン７・・・。
何度最初からやってもこうなるので仕方なく次のコマンドでアップグレードする。

```bash
$ ng update @angular/cli @angular/core
```

バージョン確認。

```bash
$ ng --version
    _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 8.3.19
Node: 10.15.3
OS: win32 x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.19
@angular-devkit/build-angular     0.803.19
@angular-devkit/build-optimizer   0.803.19
@angular-devkit/build-webpack     0.803.19
@angular-devkit/core              8.3.19
@angular-devkit/schematics        8.3.19
@angular/cli                      8.3.19
@ngtools/webpack                  8.3.19
@schematics/angular               8.3.19
@schematics/update                0.803.19
rxjs                              6.5.3
typescript                        3.5.3
webpack                           4.39.2
```
オケ。


#####Service Workerをインストール
以下のコマンド。

```bash
$ ng add @angular/pwa --project=my-app
```
インストールしたらプリフェッチ機能（デフォルトでassets内のすべてのファイル、app直下のindex.html、すべてのCSSファイル、.JSファイルをプリフェッチしてくれるよう設定されている）をngsw-config.jsonファイルで確認してみる。

***ngsw-config.json***でプリフェッチを設定。デフォルトの状態。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/c9030123-3b84-8385-b0d5-a9c3b2fc435e.png)
![Angular初期設定4.png](https://qiita-image-store.s3.amazonaws.com/0/307441/2af2214f-99f1-522f-f0ee-8f400144dc8a.png)


#####App Shellインストール（任意）
App Shellてなんだ？ 任意だが調べてみる。
「*ネイティブ アプリのように瞬時に、そしてネットワーク環境に依存せず確実に読み込めるPWA を構築するアーキテクチャの一つ。
これがどういうものかというと、まずアプリケーションを構築する静的なパーツであるナビゲーション等を予めレンダリングして index.html に組み込んでおきます。（表現方法を変えると、アプリケーションの一部分をプリレンダリングしているということです）
ユーザーはアプリケーションが瞬時に応答したと認識し体感レスポンスが向上します*」[SSR の知識ゼロから始める Angular Universal](https://qiita.com/MasanobuAkiba/items/7adcfd5050150ac9ba36#angular-%E3%81%A7%E3%81%AE%E6%A7%8B%E7%AF%89%E5%AE%9F%E8%A3%85)より。


…要はロードが早くなるようだ。しかし[Getting Started With App Shell Using Angular](https://dzone.com/articles/getting-started-with-app-shell-using-angular-7)によるとロード時間755msが711msに改善。たいして変わらない。わたしはやめておく。入れたい場合は以下のコマンド。

```bash
$ ng generate app-shell --clientProject=my-app --universalProject=my-app
```


##### Materialを使いたいのでインストール。

```cmd
$ ng add @angular/material
```

以下の様に聞かれたらthemeは好きなものを選んでエンター。

```bash
? Choose a prebuilt theme name, or "custom" for a custom theme:
  Indigo/Pink        [ Preview: https://material.angular.io?theme=indigo-pink ]
  Deep Purple/Amber  [ Preview: https://material.angular.io?theme=deeppurple-amber ]
  Pink/Blue Grey     [ Preview: https://material.angular.io?theme=pink-bluegrey ]
  Purple/Green       [ Preview: https://material.angular.io?theme=purple-green ]
> Custom
```

参考：
![Angular初期設定6.png](https://qiita-image-store.s3.amazonaws.com/0/307441/b02ee239-412e-748d-d410-8f1af9cd5631.png)
Indigo/Pink 　　　　　　　　　　　　　　　　　　　Deep Purple/Amber

![Angular初期設定5.png](https://qiita-image-store.s3.amazonaws.com/0/307441/e96a2b04-57f0-33ee-2d05-658519bff788.png)
Pink/Blue Grey　　　　　　　　　　　　　　　　　　　Purple/Green

とりあえずCustomにしておく。
次の質問は
両方とも Y を入力してエンター。

```cmd
? Set up HammerJS for gesture recognition? Y
? Set up browser animations for Angular Material? (Y/n) Y
```



<br />
###ビルド方法

以下のコマンドでまずビルド。

```bash
$ ng build --prod --output-path=dist --delete-output-path=true
```

App-shell入れてたら以下のコマンドでビルド（App-shell入れてても上のコマンドでApp-shell使わないビルドはできる）

```bash
$ ng run my-app:app-shell
```

ビルドが完了するとdistフォルダができてる。この中にコンパイルされたファイル群がある。index.htmlもある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/74d50608-21a3-3b26-bbe1-991f60d31d1d.png)

App-shellビルドした場合はdist/＜ProjectName＞というフォルダができて、その中にファイル群がある。


###動作確認

***PWA開発には以下の制限あり***
1. ng serveコマンドで動作確認できない
2. Production用のビルドを行わないと動作確認できない

上記書籍<a target="_blank" href="https://www.amazon.co.jp/gp/product/4822254534/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4822254534&linkCode=as2&tag=kokkahasan-22&linkId=942b842a41cc4a1696a75d9b81ec8862">AngularによるモダンWeb開発 基礎編 第2版</a><img src="//ir-jp.amazon-adsystem.com/e/ir?t=kokkahasan-22&l=am2&o=9&a=4822254534" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />では簡易なWebサーバーhttp-serverをローカルにインストールしhttp-serverをdist/<projectName>（ビルドファイルの吐き出し先）を見るように立ち上げて確認している。

そのやり方は以下の通り。

- どのディレクトリからでもいいので次のコマンドでhttp-serverをインストール。

```cmd
$ npm install -g http-server
```

- そしたら、プロジェクトルートのフォルダに移って、次のコマンドでhttp-serverを起動。

```cmd
$ http-server ./dist -p9000 -c-1 -o
```
./dist : distフォルダをルートディレクトリに
-p3000 : port番号を9000に指定
-c-1 : キャッシュを消してから起動
-o : ブラウザを開く

初期画面が勝手に開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/421cc6a7-e1b3-5454-abc2-74f3b355b0ae.png)



- より簡単な方法
つぎのコマンド

```bash
$ npx node-static ./dist --spa --port=9000
```
これでも同じ。
初期画面をhttp://127.0.0.1:9000/ にアクセスして開く。

<br>

F12を押してChromeデベロッパー・ツールを開く（Macの場合はCommand＋Option＋Iキー）。
ApplicationをクリックするとService Workerがあるのが見える。そしてグリーンのランプがついていて、Status activated and runningとなっている。良さそうだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/f47b607e-a381-af5e-36cd-a0917a589bce.png)


Networkをクリックしてページをリロードしてみる。するといろいろなファイルがService Workerからプリフェッチされているのがわかる。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/213aa0e7-6f29-6895-5d79-410749fb6dd8.png)


<br>
###Ivyのパフォーマンスを検証する
Angular8ではデフォルトではIvyはオフになっている。

#####Ivyなしでのパフォーマンス
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/9e06f957-288d-35da-5295-c2daa0b8e05d.png)
distフォルダのサイズは1,092,046 バイト
#####Ivyありでのパフォーマンス
オンの仕方。
以下のファイルを編集

```bash
//tsconfig.json

{
  "compilerOptions": { ... },
  "angularCompilerOptions": {
    "enableIvy": true
  }
}
```
キャッシュをクリアしてロード。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/8fb75c05-1714-fabd-018b-a3c4d5386b16.png)

Scriptingが614mgから436mgに大幅に改善。
distフォルダのサイズは1,081,833 バイト。これはほとんど変わらん。


<br />


以上。
<br>
参考：
[Angular CLI v8でPWAを作ってみよう！](https://qiita.com/puku0x/items/a6db78cc67d1eb960384)
[Getting Started With App Shell Using Angular](https://dzone.com/articles/getting-started-with-app-shell-using-angular-7)
[Angular v8がリリースされました！バンドルサイズ削減され、新レンダリングエンジンIvyのプレビュー版が利用可能に！](https://dev.classmethod.jp/client-side/angular-v8-release/)