關于圖形技術棧的一些想法
當初 React 發布一個一個新消息的時候, 大家鼓吹也激動過, Virtual DOM 本來只能渲染 DOM, 漸漸有人用來渲染 Canvas 渲染 WebGL, 還有人渲染 Terminal Simulator, 也看到有渲染 TV 的. 后面 非死book 放出大招, React Native 可以同時寫 Android 跟 iOS, 感覺一下子打開了新世界的大門.
最近搞出新聞的是 Weex, 距離 Weex 第一次露面已經挺長時間了, Weex 的目標是三端一致, 不僅僅是 非死book 那樣停留在降低開發者門檻那種程度. 而現在這樣的目標, 顯然也面臨著更大的難度, 首先就會有大量跨平臺不一致性的問題需要處理. 主要就是 iOS, Android 和 Web.
這次參加 Weex Conf 聽到了不少新東西, 覺得有很多值得思考. 比如說經歷了這么多 Native UI 動態化的嘗試, 現在的 Weex 能否達成最初的目的. 或者說怎樣形成生態和標準, 以便更快對用戶體驗做大的提升. 而且假如 Weex 走得更遠, 能否在 React Native 基礎上做競爭甚至更進一步? 未來有很多可能性.
這里我覺得另一個視角可以觀察, 如果 LLVM 生態有所了解的話, 圖形渲染引擎領域發生的變化, 某種程度上可以進行借鑒. LLVM 是 Apple 使用并開源的一個編譯器中間層, 并且是一種 IR. 有了 LLVM 之后, 編程語言可以先編譯到 LLVM 的 IR, 然后由 LLVM 進行優化, 最終編譯到各種平臺. 實現了編譯器前后端的解耦.
好處是編譯器被模塊化, 容易進行復用. 當前端需要擴展, 或者后端需要擴展, 工作量可以大大減少. 同時, 如果對于局部的模塊不滿意, 可以編寫代碼替換掉模塊, 而不是整個做一遍語言. 同時 LLVM 自身會提供強大的優化, 提高生成的代碼的效率值. 現在我們已經看到除了 Swift, 也有 Julia 和 Rust 這兩種語言直接基于 LLVM 設計. 已有的語言比如 Haskell 也提供基于 LLVM 的編譯后端, 使用 LLVM 進行優化. 可以說 LLVM 激活了一個不小的生態.
回過頭再看 Virtual DOM, 對于 Virtual DOM 來說, 它的后端也是多樣化, 能做到解耦, 它的性能優化主要由渲染引擎來實現. Virtual DOM 的前端目前主要是 React 及其方言, 但是從廣義上說, Vue 使用 snabbdom 也算是 Virtual DOM, 其他比如 virtual-dom, deku 之類的 Virtual DOM 方案也是數不勝數, 只是說沒有整合進入生態. 那么, 是否有著可能性, 通過我們制定可靠的 Virtual DOM 的 Spec, 最終形成渲染引擎技術棧的生態?
接下來說一個我的想法, 假如說拋開 DOM 重新構造技術棧, 從 OpenGL/WebGL 標準一直到實現 Business, 會是什么樣子? 參考已有的技術方案, 我畫了一個我理解的層級. 對于瀏覽器來說, 性能最高的 API 是 WebGL, 而對于互聯網公司來說的, 主要是和 Framework 打交道, 將 Framework 封裝為為公司所需要的工具鏈和開發習慣. 在中間, 則提供 Virtual DOM 和 OOP APIs 兩層, 前者便于 Framework 開發者生成 Virtual DOM, 后者便于渲染引擎開發者針對具體的渲染指令進行實現.
當然這個劃分過于理想化了, 比如 Business 當中可能直接基于 Virtual DOM 開始封裝, 跟 Framework 沒有多少差別; 或者在 Framework 當中為了處理性能以及 edge case 的情況會去直接調用 OOP APIs 甚至 WebGL 當中的代碼, 也未可知. 而且目前而言, 以 real DOM 作為 IR 的場景反倒更清晰一些, 比如在 Android 當中模擬一個 DOM tree 出來, 而 Virtual DOM 更多是一種理論當中的 IR.
這里也許會有個誤解, 就是 React 明明導向一個 FP 風格的方案, 為什么下面寫了個 OOP? 我的看法是這樣, FP 風格代碼提供高級的抽象同時會形成較大的內存開銷, 間接影響到性能. 在這個位置的 API 主要目的還是為了簡單直接地對 WebGL API 進行語法封裝, 由于 WebGL 是命令式的繁瑣操作, 并涉及到各種內存狀態的修改, 用 OOP 風格代碼較輕而且對性能影響小. 當然這也僅限 API 的語法風格, 而不是整體的代碼的架構.
其實最重要的還是怎樣優化性能. 使用 FP 是尋求整體架構的清晰, 具體到實現當中還是會引入緩存方案以減少重復計算和內存消耗, 從而減少性能的開銷. 包括 Framework, 除了提供語法糖的便利和隨之帶來的模塊復用的好處之外, 也需要提供足夠的性能. 當然, 這里說的性能, 是復雜應用的性能, 因為簡單的應用某種程度上不需要抽象, 只有對于通用的渲染邏輯的抽象進行優化, 在這個場景里才有意義.
最后回到 Weex, 對照這個分層, Weex 主要覆蓋了 Framework 和 Virtual DOM 兩層的內容, 而在 OOP APIs 方面, 繼續對 Android 和 iOS 做了一定的封裝. OOP APIs 成了 IR. React 方案當中, IR 的范圍還可以擴大到 Virtual DOM, 這在 Weex 和 Rax 方案中似乎由于 Framework 的差異并不是復用. 當然簡單地討論整個分層有多少復用的部分沒有多大意義, 我主要是認為這樣一套分層的思路可以為生態當中職能的劃分提供一些參考, 以便我們從關鍵節點觸發連接好生態當中各個片段. 以前端每年新的 Framework 搶風頭的周期的, 賀老(@賀師俊)對 Weex 的三年過氣的擔憂我覺得觸發的可能性很大. 而 Virtual DOM 這一層影響較小, 底層 OOP APIs 會受到系統影響, 但不會像開發者口味那么善變.
還是那句話, 畫圖形出來往往是理想化的, 實際場景當中復雜太多了. 雖然我喜歡把渲染引擎跟虛擬機進行類比, 但是圖形界面自身的特點也是蠻多的, 最終搬過來也只有 IR 這么個法說罷了.
來自:https://zhuanlan.zhihu.com/p/24901316