*こちらはOpt Technologies Advent Calendar 2016の12日目になります。
遅刻マンでどうもすみません
というわけで@_sisisinです
Angular2といえばAoTみたいなところがあるらしいのと、webpack2のRCも出たので、そろそろ触ってみる頃合いでは!?という機運を感じたので試してみました
AoT Compileとは?
- Ahead of Time Compileの略
- Angular2系で書かれたアプリをビルドする際に、templateのhtmlも一緒にコンパイルしちゃおうというもの
- 一言で言ってしまうと、ビルド時に
tscの代わりにngc(パッケージは@angualr/compiler-cli)を使うことで実現する- *一言で言ったものの、
ngcを使えるようにするには他にも色々やらなきゃいけないことはもちろんあります
- *一言で言ったものの、
- 概ね @Quramy さんのAngular AoTガイドを参照していただければ色々わかります
とりあえず最小構成
なにはともあれ最小構成で試してみる
リポジトリ:https://github.com/sisisin-sandbox/ng-aot
構成
|-- dist/
| `-- budnle.js
|
|-- _tmp/ # TypeScriptのトランスパイル結果ファイル置き場
|
|-- _tmp_aot/ # angular compiler-cliが自動生成するAoT CompileされたTypeScriptファイル置き場
|
|-- src/
| |-- app.component.css
| |-- app.component.html
| |-- app.component.ts
| |-- app.module.ts
| |-- main.aot.ts
| |-- main.ts
| `-- polyfills.ts
|
|- index.html
|- package.json
|- tsconfig.aot.json
|- tsconfig.json
|- webpack.config.dev.js
`- webpack.config.prod.js
解説
開発時はAoTを使わず、本番ではAoTを利用するというユースケースを想定してます
そのためにAoTを使用する/しないを使い分けるためにwebpack.confやtsconfig,アプリのメインエントリポイントをわけています
開発用ビルドについて
開発時はtsconfig.json,webpack.config.dev.jsを利用してmain.tsをビルドします。
import './polyfills';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
こちらはいつものAngular2系のエントリポイントですね。
platformBrowserDynamicでAppModuleを実行しています。
なお、tsconfigのexcludeにmain.aot.tsを入れています。
後述しますが、main.aot.tsはngcの生成するtsファイルを参照しているので、普通にtscでビルドしようとするとビルドが通りません
本番用(AoT Compile)ビルドについて
本番ではtsconfig.aot.json,webpack.config.prod.jsの設定ファイルでngcを利用してmain.aot.tsをビルドします
import './polyfills';
import { platformBrowser } from '@angular/platform-browser';
import { AppModuleNgFactory } from '../_tmp_aot/app/app.module.ngfactory';
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);
ここでは@angular/platform-browserに含まれているplatformBrowserというモジュールで、AppModuleNgFactoryを実行しています。
AppModuleNgFactoryはngcコマンドにて自動で生成されるモジュールになっています。
ngcの出力結果には他にもapp.component.css.shim.ngstyle.tsやapp.component.ngfactory.tsなどがあり、これらはcssやhtmlをTypeScriptのコードに落とし込んだものになっています。
これによって静的解析が出来るようになるわけですね。
AoTの効果について
開発者ツールを覗いてみました
ファイルサイズ比較
| AoT未使用 | AoT使用 | |
|---|---|---|
| minifyなし | 6.4MB | 3.2MB |
| minify済み | 734KB | 342KB |
| AoT未使用 | AoT使用 |
|---|---|
| 388ms | 166ms |
AoT未使用だと大体300~400msかかっていますが、AoT使用だと160~200msぐらいに収まっています(AoT使用でidleがやたら長いのが気になりますが。。。
にしても歴然の差ですね。
hello worldレベルのコードでこの差なので絶対に取り入れたいという気持ちが強くなります
さすがに実行時間についてはそんなに変わらないだろと思ったのに結構バッチリ差が出てて笑っちゃいました
まとめ
Angular2系をやるならぜひともAoTはやってやっていこう!
おまけ
compiler-cli@2.3.1では不具合があるようで、TypeScript2.1.3でngcを実行するとngfactory.tsを吐き出してくれません。
自分はこれで半日近く悩まされました。。。
https://github.com/angular/angular/issues/13204
issueも上がっているようなので遠からず解決することでしょう。
ご利用の際はお気をつけて。

