跨平臺
關於BeesAndroid專案
BeesAndroid專案提供了一系列的工具、理論分析與方法論,旨在降低Android系統原始碼的閱讀門檻,讓讀者更好的理解Android系統的設計與實現。第一次閱覽本系列文章,請參見導讀,更多文章請參見文章目錄。
自己接觸跨平臺容器也有快一年的時間了,站在前人的肩膀上,結合著自己的理解,聊一聊對跨平臺容器生態的看法,不當之處多多指正。
背景與歷史
跨平臺技術解決的核心問題
- 效率:解決在多應用、多平臺、多容器上開發效率的問題,一碼多端,業務快跑。
- 效能:解決的是業務的效能和體驗問題。
跨平臺技術的評價指標
- 技術棧
- 研發效率
- 動態化
- 多端一致性
- 效能體驗
- 維護成本
- 社群生態
跨平臺技術的渲染方案
- WebView渲染:依賴WebView進行渲染,在功能和效能上由妥協,例如PhoneGap、Cordova、小程式(有的小程式底層也採用了ReactNative等渲染方案)等。
- 原生渲染:上層擁抱W3C,通過中間層把前端框架翻譯為原生控制元件,例如ReactNative+React、Weex+Vue的組合,這種方案多了一層轉譯層,效能上有損耗。隨著原生系統的升級,在相容性上也會有問題。
- 自建渲染:自建渲染框架,底層使用Skia等圖形庫進行渲染,例如Flutter、Unity。
跨平臺技術的發展歷史
這裡面提一點,React Native和Weex額外增加轉譯層的做法,目前看來在效能上已經遇到瓶頸,而且系統升級以後,框架維護成本較高,如果未來沒有大的重構的話,目前處於走下坡路的狀態,其他的方案都處於並存的狀態。
跨平臺框架 | Hybrid App | React Native | Weex | 快應用 | 小程式 | Flutter |
---|---|---|---|---|---|---|
時間 | 2011 | 2015 | 2016 | 2017 | 2017 | 2018 |
開發方 | 多個 | Alibaba | 手機廠商 | 多個 | ||
支援平臺 | Android iOS Web |
Android iOS |
Android iOS Web |
Android | Android iOS |
Android iOS Web |
渲染容器 | Android:WebView iOS:WKWebView |
原生容器 | 原生容器 | 原生容器 | 多容器 | 原生容器 |
開發語言 | JavaScript | JavaScript(React) | JavaScript(Vue) | JavaScript(原生) | JavaScript(小程式語法) |
Dart |
研發效率 | 高 | 一般 | 一般 | 一般 | 高 | 一般 |
技術棧 | 前端 | 偏前端 | 偏前端 | 偏前端 | 偏前端 | 偏客戶端 |
動態化 | 支援 | 支援 | 支援 | 支援 | 支援 | 支援 |
多端一致性 | 高 | 一般 | 一般 | 無iOS | 高 | 高 |
效能體驗 | 差 | 一般 | 一般 | 一般 | 一般 | 好 |
維護成本 | 低 | 高 | 高 | 高 | 低 | 低 |
社群生態 | 活躍 | 不活躍 | 不活躍 | 不活躍 | 活躍 | 活躍 |
注:上面提到渲染效能,只是說在一般概括性的說法,拋開優化談效能都是不可取的,因此要區分對待。
從發展歷程我們來總結一下跨平臺容器技術實現的變化
- Hybrid App:JavaScript開發+WebView渲染
- React Native/Weex/快應用:JavaScript開發+原生渲染
- 小程式:JavaScript開發+多容器(多種渲染方式)
- Flutter:Dart開發+原生渲染
容器生態
跨平臺容器生態至少可以分為三個方面:
- 前端框架生態
- 容器統一層
- 容器層
前端框架生態
前端框架生態直接面向的是業務,它應該具備兩個特點:
- 擁抱W3C生態
- 相對穩定性
它應該是擁抱W3C生態的。W3C生態是一個繁榮且充滿活力的生態,它會發展的更久更遠。試圖拋棄W3C生態,自建子集的做法很難走的長遠。這從微信小程式、Flutter都推出for web系列就能看出端倪。
**它應該是相對穩定的。**不能說我們每換一套容器,前端的業務就需要重新寫一遍,例如我們之前做H5容器,後來做小程式容器,因為DSL不通,前端要花大力氣將業務重寫。雖然小程式是一碼多端,但是我認為這並沒有解決效率問題,主要存在兩個問題:
- 前端的學習成本增加,小程式的DSL還算簡單,Flutter的Widget體系學習起來就需要花上一點時間,這些對於團隊來說都是成本。
- 業務程式碼重寫,大量邏輯需要梳理,而且老業務並不一定都適合遷移到新容器上,比如小程式本來就是個很輕量的解決方案,但是我們在上面堆積了很多功能,造成了嚴重的體驗問題。
在這種情況下,業務很難實現快速奔跑。所以說不管底層容器怎麼變,前端的框架一定是相對穩定的。而這種穩定性就有賴於容器統一層。
容器統一層
容器統一層是在前端框架和容器層之間的一個層級。它定義了容器提供的基本能力,這些能力就像協議一樣,是相對穩定的。
協議是非常重要的,就像OpenGL協議一樣,有了OpenGL協議,不管底層的渲染方案如何實現,上層的呼叫是不用變的。對於我們的業務也是一樣,圍繞著容器統一層,我們需要沉澱通用的解決方案。
- 統一API解決方案
- 統一效能解決方案
- 統一元件解決方案
- 統一配套設施解決方案
- 等等
這些東西不能說每搞一套容器,我們都要大刀闊斧重來一遍,這種做法是有問題的。已經做過的東西,遇到新的技術就推倒重來,只能說明以前定義的方案考慮不周全,沒有考慮沉澱統一和擴充套件的情況。
如果我們自顧自的一遍遍做著功能重複的技術方案,業務能等著我們嗎。
容器層
容器層的迭代核心是為了在解決效率問題的基礎上最大化的解決效能和體驗問題。
早期的ReactNative模式解決了效率了問題,但是多了一個通訊層(ReactNative是依靠將虛擬DOM的資訊傳遞給原生,然後原生根據這些佈局資訊構建對應的原生控制元件樹來實現的原生渲染)存在效能問題,而且這種轉譯的方式需要適配系統版本,帶來更多的相容性問題。
微信後續又推出了小程式方案,在我看來,小程式方案不像是一個技術方案,它更像是一個商業解決方案,解決了平臺大流量規範管理和分發的問題,給業務方提供通用的技術解決方案,當然小程式底層的渲染方案也是多種多樣的。
後起之秀Flutter解決的痛點是效能能力,它自建了一套GUI系統,底層直接呼叫Skia圖形庫進行渲染(與Android的機制一樣),進而實現了原生渲染。但是它基於開發效率、效能以及自身生態等因素的考慮最終選擇了Dart,這種做法無疑是直接拋棄了繁榮的前端生態,就跨平臺容器的發展歷史來看,在解決效率與效能的基礎上,最大化的擁抱W3C生態,可能是未來最好的方向。Flutter目前也推出了Flutter for Web,從它的思路來看,是先打通Android與iOS,再逐步向Web滲透,我們期待它的表現。
容器技術是動態向前發展的,我們今年搞Flutter,明年可能還會搞其他技術方案。在方案變遷的過程中,我們需要保證業務快速平滑的過度,而不是每次大刀闊斧的再來一遍。
隨著手機效能的提升,WebView的效能也越來越好,Flutter又為解決效能問題提供了新的思路,一個基礎設施完善,體驗至上,一碼多端的跨平臺容器生態值得期待。