本篇文章進行來學習Angular框架,帶大家了解一下Ivy編譯器中的增量DOM,希望對大家有所幫助!
作為“為大型前端項目”而設計的前端框架,Angular 其實有許多值得參考和學習的設計,本系列主要用于研究這些設計和功能的實現原理。本文圍繞 Angular 的核心功能 Ivy 編譯器,介紹其中的增量 DOM 設計。【相關教程推薦:《angular教程》】
在介紹前端框架的時候,我常常會介紹到模板引擎。對于模板引擎的渲染過程,像 Vue/React 這樣的框架里,使用了虛擬 DOM 這樣的設計。
在 Angular Ivy 編譯器中,并沒有使用虛擬 DOM,而且使用了增量 DOM。
增量 DOM
在 Ivy 編譯器里,模板編譯后的產物與 View Engine 不一樣了,這是為了支持單獨編譯、增量編譯等能力。
比如,<span>My name is {{name}}</span>
這句模板代碼,在 Ivy 編譯器中編譯后的代碼大概長這個樣子:
// create mode if (rf & RenderFlags.Create) { elementStart(0, "span"); text(1); elementEnd(); } // update mode if (rf & RenderFlags.Update) { textBinding(1, interpolation1("My name is", ctx.name)); }
可以看到,相比于 View Engine 中的elementDef(0,null,null,1,'span',...),
,elementStart()
、elementEnd()
這些 API 顯得更加清爽,它們使用的便是增量 DOM 的設計。
增量 DOM vs 虛擬 DOM
虛擬 DOM 想必大家都已經有所了解,它的核心計算過程包括:
-
用 JavaScript 對象模擬 DOM 樹,得到一棵虛擬 DOM 樹。
-
當頁面數據變更時,生成新的虛擬 DOM 樹,比較新舊兩棵虛擬 DOM 樹的差異。
-
把差異應用到真正的 DOM 樹上。
雖然虛擬 DOM 解決了頁面被頻繁更新和渲染帶來的性能問題,但傳統虛擬 DOM 依然有以下性能瓶頸:
- 在單個組件內部依然需要遍歷該組件的整個虛擬 DOM 樹
- 在一些組件整個模版內只有少量動態節點的情況下,這些遍歷都是性能的浪費
- 遞歸遍歷和更新邏輯容易導致 UI 渲染被阻塞,用戶體驗下降
針對這些情況,React 和 Vue 等框架也有