angular2 JIT and AOT

為什么需要編譯

Angular應(yīng)用中包含的組件、HTML模板(比如:@Directive、@Component、@NgModule、@Pipe)很多都是JS VM無法解析的,所以在瀏覽器渲染應(yīng)用之前,組件和模板必須要被Angular編譯器轉(zhuǎn)換為可以執(zhí)行的JavaScript。

angular2編譯模式

在 Angular 2 中有兩種編譯模式:

  • JIT - Just-In-Time
  • AOT - Ahead-Of-Time

JIT事件流:
開發(fā)流程:

  • 使用TypeScript開發(fā)Angular應(yīng)用(此處以ts舉例)
  • tsc編譯
  • 構(gòu)建
  • 壓縮
  • 部署

用戶打開瀏覽器,他將經(jīng)歷以下步驟 (沒有嚴(yán)格的CSP):

  • 下載所有的JavaScript資源
  • 啟動Angular
  • 通過JIT 編譯處理生產(chǎn)js代碼
  • 渲染應(yīng)用


AOT事件流:

  • 使用Typescript開發(fā)Angular 應(yīng)用
  • 使用 ngc來編譯應(yīng)用(目前的ngc編譯報錯還不太好用,angular團(tuán)隊正在用tsc的方式進(jìn)行優(yōu)化,據(jù)說很快就會發(fā)包)
  • 模板會被ngc編譯成TypeScript文件(通常是)
  • TypeScript編譯為JavaScript代碼
  • 構(gòu)建
  • 壓縮
  • 部署

用戶打開瀏覽器,他將經(jīng)歷以下步驟:

  • 下載所有的資源
  • 啟動Angular
  • 渲染應(yīng)用


aot將compile的過程放在應(yīng)用部署前,所以瀏覽器端承載的工作量就會大幅度減少,相應(yīng)的頁面加載時間也會大幅度減少,這也就意味著更快更好的用戶體驗。

JIT vs AOT:

編譯方式 編譯時機 構(gòu)建速度 打包大小 性能/渲染速度 模板錯誤檢查時間 安全性
JIT app運行時 - - app運行時
AOT app構(gòu)建階段 - 更快 app構(gòu)建階段

AOT優(yōu)勢:

  • 渲染得更快
    使用AOT,瀏覽器下載預(yù)編譯版本的應(yīng)用程序。 瀏覽器直接加載運行代碼,所以它可以立即渲染該應(yīng)用,而不用等應(yīng)用完成首次編譯,我們兩個項目AOT加載速度相比JIT有3-5倍的提高

  • 需要的異步請求更少
    編譯器把外部HTML模板和CSS樣式表內(nèi)聯(lián)到了該應(yīng)用的JavaScript中。 消除了用來下載那些源文件的Ajax請求。

  • 需要下載的Angular框架體積更小
    如果應(yīng)用已經(jīng)編譯過了,自然不需要再下載Angular編譯器了。 該編譯器差不多占了Angular自身體積的一半兒,所以,省略它可以顯著減小應(yīng)用的體積。但是angular采用 Code Generation 的方式,生成的 ts/js 代碼肯定是會比原來的 html 的文件大小要大的,所以在應(yīng)用足夠大(模版足夠多)的情況下 AOT 的大小是可以反超 JIT 的大小的,很不幸,我們項目就是如此

  • 提早檢測模板錯誤
    AOT編譯器在構(gòu)建過程中檢測和報告模板綁定錯誤,避免用戶遇到這些錯誤。

  • 更安全
    AOT編譯遠(yuǎn)在HTML模版和組件被服務(wù)到客戶端之前,將它們編譯到JavaScript文件。沒有模版可以閱讀,沒有高風(fēng)險客戶端HTML或JavaScript可利用,所以注入攻擊的機會較少

JIT優(yōu)勢:
編譯時間短,除非確實有動態(tài)組件的需求,否則jit唯一的優(yōu)勢就是能用來做在線 Demo和開發(fā)調(diào)試,參考知乎答案

我們兩個項目AOT和JIT對比效果:
項目A:

編譯方式 打包大小 渲染速度
JIT 5.86M
AOT 10.8M

項目B:

編譯方式 打包大小 渲染速度
JIT 4.12M
AOT 6.21M

官方在View 和 DI 上了 View Engine 后aot編譯后沒有太多靜態(tài)文件了,目前aot的編譯大小已經(jīng)低于jit(2017/10/19更新)

懶加載

懶加載也叫延遲加載,即在需要的時候進(jìn)行加載,隨用隨載

在單頁面應(yīng)用中,如果沒有應(yīng)用懶加載,進(jìn)入首頁時會導(dǎo)致需要加載的內(nèi)容過多,延時過長,不利于用戶體驗

運用懶加載將頁面進(jìn)行劃分,按需加載頁面,可以分擔(dān)首頁所承擔(dān)的加載壓力,減少加載用時

如果對首屏啟動有更嚴(yán)格的要求,最好采用服務(wù)端渲染

angular2懶加載可以參考官方文檔

搖樹優(yōu)化:

作用:消除unused code
原理:通過跟蹤import和export語句進(jìn)行靜態(tài)分析,排除那些被導(dǎo)出過但又從未被導(dǎo)入的代碼(ES6 modules 的靜態(tài)特性)

目前大部分工具只能對ES2015模塊搖樹,因為那里有import和export語句,所以需要將ts編譯成es2015(通過tsconfig配置實現(xiàn))

  • 搖樹優(yōu)化詳細(xì)介紹可以參考angular官方文檔
  • gulp+rollup搖樹優(yōu)化可以參考angular-seed
  • webpack2自帶了tree-shaking,配置可以參考工程angular-starter
  • angular-cli搭建工程:推薦使用,已經(jīng)幫你集成,不需要再去繁瑣配置各種打包搖樹優(yōu)化等

webpack2的搖樹和rollup搖樹區(qū)別可以參考知乎上這個回答

webpack2注意事項

項目目前使用的是webpack2,總結(jié)了下開發(fā)過程中遇到的坑:

  • ngc-webpack不要設(shè)置resourceOverride,否則打包后的圖片url等會有問題
  • "JavaScript heap out of memory"可以通過設(shè)置node參數(shù) node --max_old_space_size=4096(如不管用,參數(shù)可以設(shè)置更大試試)
  • typescript使用2.0以上版本(搖樹需要)
  • 使用awesome-typescript-loader包的2.x及以上版本(搖樹需要)
  • 保證我們的應(yīng)用和Angular2庫代碼在同一個位置(搖樹需要)
  • UglifyJsPlugin壓縮代碼, Webpack2可以刪除Bundle中未使用的引用代碼,但不會從Bundle中刪除未使用的代碼,在這種情況下就需要使用UglifyJsPlugin,它能夠智能的移除未使用的代碼
  • 使用AOT在build時,瀏覽器渲染快,但是在模板足夠多的情況下大于jit打包體積,配合gzip使用最佳,項目使用的是nginx,gzip在nginx詳細(xì)配置可參考這篇文章

AOT注意事項

由于AoT的特性,部分在JIT模式下可用的方法在AoT下是不可行或者官方不建議的,開發(fā)代碼的童鞋在aot模式下需要注意額外注意這些情況,github上8000+star的angular-starter工程總結(jié)如下(英文捉急,就不在這獻(xiàn)丑翻譯了):

  • Don’t use require statements for your templates or styles, use styleUrls and templateUrls, the angular2-template-loader plugin will change it to require at build time.
  • Don’t use default exports.
  • Don’t use form.controls.controlName, use form.get(‘controlName’)
  • Don’t use control.errors?.someError, use control.hasError(‘someError’)
  • Don’t use functions in your providers, routes or declarations, export a function and then reference that function name
  • @Inputs, @Outputs, View or Content Child(ren), Hostbindings, and any field you use from the template or annotate for Angular should be public

補充一些我們項目開發(fā)過程中遇到的問題,O(∩_∩)O 都是開發(fā)時代碼不規(guī)范埋下的坑:

  • 定義的函數(shù)傳參必須匹配
  • 等和非等判斷類型必須一致
  • 未在ts定義的變量不要在html模板中使用

總結(jié)

推薦大家在dev時使用jit可以提高開發(fā)調(diào)試效率,在prod時使用aot

參考:
http://blog.mgechev.com/2016/08/14/ahead-of-time-compilation-angular-offline-precompilation/
http://blog.rangle.io/optimize-your-angular2-application-with-tree-shaking/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 中文翻譯 ng help ng build 構(gòu)建您的應(yīng)用程序并將其放入輸出路徑(dist /默認(rèn)情況下)。 別名:...
    4ea0af17fd67閱讀 2,128評論 0 0
  • 因個人精力有限,暫停簡書的維護(hù),歡迎大家關(guān)注我的知乎https://www.zhihu.com/people/we...
    尾尾閱讀 1,303評論 3 13
  • AOT是Ahead of Time compile 的縮寫,顧名思義提前編譯。 關(guān)于AOT的好處,在這里就不一一細(xì)...
    lolivialucky閱讀 5,899評論 0 4
  • 一個智慧的父母一定要學(xué)會在孩子面前示弱,讓孩子具有心理優(yōu)勢,讓孩子在你面前體驗贏的感覺,以此推動孩子建立自信體系。...
    善默勤容閱讀 433評論 0 0
  • 早起 人們都說堅持過一周,一切都會變得簡單起來。 晨間日記: 喝水+早餐 參加早會 整理趕集收到的簡歷 準(zhǔn)備備用金...
    理想幾塊錢一斤閱讀 234評論 0 0

友情鏈接更多精彩內(nèi)容