Angular--AOT和JIT編譯

概覽

衆所周知, angular應用在可執行以前, angular應用中的組件和模板必須被轉化爲能夠被瀏覽器識別的javascript代碼, 而這種轉化正是經過angualr自身的編譯器所執行的.javascript

angular提供了兩種編譯方式, 即AOT(預編譯)和JIT(即便編譯), 其中JIT爲默認的編譯方式java

AOT即 Ahead of time, 是指在構建時進行編譯, 即在服務端即完成了編譯 JIt即 Just-in-Time, 在運行期間編譯該應用,也就是在應用加載時。node

AOT vs JIT

實際上只有一個編譯器,二者的區別只是編譯的時機和工具不一樣webpack

JIT編譯致使運行期間的性能損耗。 因爲須要在瀏覽器中執行這個編譯過程,視圖須要花更長時間才能渲染出來。 因爲應用包含了Angular編譯器以及大量實際上並不須要的庫代碼,因此文件體積也會更大。 更大的應用須要更長的時間進行傳輸,加載也更慢。web

編譯能夠發現一些組件模板綁定錯誤。JIT編譯在運行時才揭露它們,那樣有點太晚了。npm

而預編譯(AOT)會在構建時編譯,這樣能夠在早期截獲模板錯誤,提升應用性能。json

#JiT編譯模式的流程bootstrap

一個典型的jiT應用的開發流程大概是:瀏覽器

  • 使用TypeScript開發Angular應用
  • 使用tsc來編譯這個應用的ts代碼
  • 打包
  • 壓縮
  • 部署

一旦把app部署好了,而且用戶在瀏覽器中打開了這個app,下面這些事情會逐一進行:bash

  • 瀏覽器下載js代碼
  • Angular啓動
  • Angular在瀏覽器中開始JiT編譯的過程,例如生成app中各個組件的js代碼
  • 應用頁面得以渲染

相對的,使用AoT模式的應用的開發流程是:

  • 使用TypeScript開發Angular應用
  • 使用ngc來編譯應用
    • 使用Angular編譯器對模板進行編譯,生成TypeScript代碼
    • TypesScript代碼編譯爲JavaScript代碼
  • 打包
  • 壓縮
  • 部署

雖然前面的過程稍稍複雜,可是用戶這一側的事情就變簡單了:

  • 下載全部代碼
  • Angular啓動
  • 應用頁面得以渲染

歸納起來,Angular中的JitAoT的主要區別是:

  • 編譯過程發生的時機
  • JiT生成的是JS代碼,而AoT生成的是TS代碼。這主要是由於JiT是在瀏覽器中進行的,它徹底不必生成TS代碼,而是直接生產了JS代碼。

深刻AOT編譯

AOT編譯的配置

安裝npm依賴

npm install @angular/compiler-cli @angular/platform-server --save

複製代碼

把下列npm便利腳本添加到package.json中,以便用一條命令就能夠完成編譯

"build:aot": "ngc -p tsconfig-aot.json 複製代碼

@angular/compiler-cli包中提供的ngc編譯器來代替TypeScript編譯器(tsc)。

配置tsconfig-aot.json 文件

只需將tsconfig.json 文件複製過來進行修改便可

{
  "compilerOptions": {
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": ["es2015", "dom"],
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "typeRoots": [
      "./node_modules/@types/"
    ]
  },

  "files": [
    "src/app/app.module.ts",
    "src/main.ts"
  ],

  "angularCompilerOptions": {
   "genDir": "aot",
   "skipMetadataEmit" : true
 }
}
複製代碼

compilerOptions部分只修改了一個屬性:**把module設置爲es2015(爲後面搖樹優化作準備)

ngc區真正新增的內容是底部的angularCompilerOptions。 它的genDir屬性告訴編譯器把編譯結果保存在新的aot目錄下

"skipMetadataEmit" : true屬性阻止編譯器爲編譯後的應用生成元數據文件。 當輸出成TypeScript文件時,元數據並非必須的,所以不須要包含它們。

啓動AOT編譯:

node_modules/.bin/ngc -p tsconfig-aot.json
複製代碼

編譯完成後生成了一堆NgFactory文件,不要編輯這些NgFactory!從新編譯時會替換這些文件.

改變引導方式main.ts 文件

platformBrowserDynamic.bootstrap改爲使用platformBrowser().bootstrapModuleFactory並把AppModuleNgFactory的AOT編譯結果傳給它。

import { platformBrowser }    from '@angular/platform-browser';
import { AppModuleNgFactory } from '../aot/src/app/app.module.ngfactory';

console.log('Running AOT compiled');
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

複製代碼

搖樹優化(Tree shaking)

搖樹優化是指經過跟蹤importexport語句來對應用進行靜態分析,遍歷依賴圖譜,而且搖掉用不到的代碼,經過移除源碼和庫代碼中用不到的部分,搖樹優化能夠大幅縮減應用的下載體積

搖樹優化可以在咱們最終的Bundle中移除掉咱們應用中沒有使用到的代碼。這是減小應用程序佔用空間的最有效的技術之一。

目前webpack2已經支持tree shaking, 官網介紹的是Rollup在angular中的使用

知乎上關於tree shaking的介紹

開發器使用JIT, 產品期使用AOT

目前,AOT編譯和搖樹優化對開發來講,佔用的時間太多了。這將在將來獲得改變。 當前的最佳實踐是在開發器使用JIT編譯,而後在發佈產品前切換到AOT編譯

相關文章
相關標籤/搜索