近年大約六個月一次的 Angular 重要版本更新很快就要來了! 其中最矚目的莫過於Angular v2 第三代的 rendering engine : Angular Ivy ,當中有什麼值得我們留意的?


Angular Ivy 早在 2018 年的 4 月 的 Ng-conf 中就公佈了。有新的 rendering engine 出現,官方所強調的都莫過於容量細、速度較快、編碼層面上更簡單。不過,有幾點是 Angular 今次想透過 Ivy 來解決的:

  1. Ivy 為了改善用家體驗,使瀏覽器需要下載的內容更少,從而使應用程式的啟動時間加快。
  2. Ivy 通過簡化 API 和 構建系統(build system),幫助開發人員更容易編寫源碼。
  3. Ivy 通過將編譯管道(compilation pipeline)變得更平易近人,使得第三方的開發更為可能,有助 Angular 社區發展。

不過新事物的出現,程式員第一樣關心的事情就是用不用改之前的代碼?答案是:

100% Backwards Compatible!

皆因 Google 本身也有 600+ 個服務都是用 Angular 來編寫,Google 亦不容許當新的 Angular 版本推出時,仍然使用舊的版本,所以 Angular 幾乎不可能做出一個具斷裂性的改變,所以各位程式員請放心使用。

在編碼層面上,Ivy 有幾個重大的更新,其中包括:

  1. Locality
  2. Tree-Shaking
  3. Low Memory Footprint

Locality

「locality」看來是 Angular 開發團隊所提出的新名詞,這裡容許我譯作為局部性局部性的意思是指當 Angular 的編譯器(compiler)翻譯模板(template)的時候,編譯器只會允許使用對其來說是 屬於該局部local)的信息,亦即是那些由其 component decorator 與 class 所定義的信息。當需要重新編譯某一組件時,因為不直接關聯的依賴(dependency)不會牽涉在編譯的過程之內,所以就能夠實行累加組建(incremental build,毋須每次都要渲染一整個全新的 virtual DOM tree,重新編譯的時間較短,產生出來的代碼體積亦較小。

Ng-conf 亦提到局部性的其他好處:

  1. 允許第三方的 library 將預先編譯好的模板,直接發送到 NPM。對於使用這些 library 的應用程式來說,能夠簡化和加速編譯過程。
  2. AoT / JIT 所產生代碼近乎一樣,使開發、測試時能夠容易地合用這兩種代碼。
  3. metadata.json 消失了,這大大簡化第三方 library 的發佈及開發,以及和現存工具鏈(tool chain)的互用性
  4. 大量減省編譯圖(compilation graph),這能簡化組建工具,重建大型項目的時間亦能縮短。
  5. 允許元編程(meta-programming),能夠令 component 可以在執行期(run time)內創建,Higher Order Components 亦能完全實現。

Tree-Shaking

比起大量運用 Virtual DOM 的主流 framework,Ivy 所用的 incremental DOM 更有利於Tree-Shaking。Tree-Shaking 是 死碼刪除 (Dead code elimination/DCE) 的一種, 它的用途是移除對程式執行結果沒有任何影響的源碼。不過相對於傳統DCE 只是移除永遠不能執行的代碼,Tree-Shaking 能夠從程式的入口點開始,並且透過 靜態程式分析 (Static program analysis)來移除不會執行的代碼。 上代的 Renderer2 和 Ivy Render 同樣都有運用Tree-Shaking,但 Ivy 將源碼分解為更細小、更原子化的 function,更有利 Tree-Shaking 的運用,從而產生更小的 bundle。

以下的 Angular 特性都是能夠被 Tree-Shaking:

  • Template syntax
  • Dependency injection
  • Content projection
  • Structural directives
  • Life cycle hooks
  • Pipes
  • Queries
  • Listeners
Source: ngConf-2018 keynote

譬如上圖的例子,由於只有 someFnmain 引用,而 unusedFn 沒有,所以最終Ivy Render 編譯出來的bundle 就不會包含unusedFn這個 function了。

Source: ngConf-2018 keynote

但如果 unusedFn 牽涉到條件上的檢查,即使條件最終為false而不會用到unusedFn,Ivy Render 編譯出來的bundle 仍然會保留unusedFn。基於靜態程式分析只會嘗試在不實際運行程式的情況下,找出所需內容,而它通常要假設最壞的情況以確保編譯出來的程式是正確無誤,Ivy Render並不會清楚在 runtime 時該值為何,就會保留unusedFn。所以編寫源碼時就要避免這種情況,不要過份依賴 Ivy Render 的 Tree-Shaking。


Low Memory Footprint

Memory Footprint ( 記憶足跡指的是一個程式在運行時所需/引用的主記憶體數量,而使用 incremental DOM 的 Ivy 就能降低記憶足跡。

主流 framework 所使用的 virtual DOM 在每一次重新渲染的時候,會整棵DOM tree 也會重新建立一次。

(From: https://blog.nrwl.io/understanding-angular-ivy-incremental-dom-and-virtual-dom-243be844bf36

而 incremental DOM 因為當 DOM 節點有加減才需要分配記憶體,除此之外就無需使用內存空間。而由於大部分的渲染和模板調用( template calls)都毋須DOM 節點上的改變,相對地就能大幅減少運行程式時的記憶體。

(From: https://blog.nrwl.io/understanding-angular-ivy-incremental-dom-and-virtual-dom-243be844bf36

Angular v8-rc4 版本在 May 16, 2019 已經發佈,Angular v8 相信很快就會推出,我們相當期待正式版的 Ivy rendering engine 讓程式員毋須大量重寫源碼,就能夠更有效運用前台資源。

更多資訊可以留意 ONES Publication 定期發佈的文章,亦可以聯絡我們,我們的網址是: https://ones.software

Ref:

https://juristr.com/blog/2019/05/Angular-8-and-the-Future-NGConf-2019-Roundup/#ivy-features

https://is-angular-ivy-ready.firebaseapp.com/#/status

https://blog.angular.io/a-plan-for-version-8-0-and-ivy-b3318dfc19f7

https://blog.nrwl.io/understanding-angular-ivy-incremental-dom-and-virtual-dom-243be844bf36

https://medium.com/grapecity/what-to-expect-in-angular-8-940b217b63cb

https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking

https://www.telerik.com/blogs/an-early-look-at-angular-8-get-ready-for-opt-in-ivy-preview

https://www.zhihu.com/question/266923267/answer/316279829

https://www.telerik.com/blogs/first-look-angular-ivy

https://juejin.im/entry/5c01665a51882516cd70c661

https://blog.nrwl.io/metaprogramming-higher-order-components-and-mixins-with-angular-ivy-75748fcbc310

https://blog.angularindepth.com/ivy-engine-in-angular-first-in-depth-look-at-compilation-runtime-and-change-detection-876751edd9fd

https://blog.angularindepth.com/inside-ivy-exploring-the-new-angular-compiler-ebf85141cee1

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。