前言
你們好,我是
simbawu ,
@BooheeFE Team Leader,關於這篇文章,有問題歡迎來
這裏討論。
隨着移動互聯網的普及和快速發展,手機成了互聯網行業最大的流量分發入口。以及隨着5G的快速發展,將來愈來愈多的「端」也會如雨後春筍般快速興起。而「快」做爲互聯網的生存之道,爲了佔領市場,企業也會積極跟進,快速佈局。同一個應用,各個「端」獨立開發,不只開發週期長,並且人員成本高。同時,做爲技術人員,也不該該知足於這種重複、低能的工做狀態。在這樣的形勢下,跨平臺的技術方案也受到愈來愈多人和企業的關注。接下來,我將從原理、優缺點等方面爲你們分享《跨平臺技術演進》。javascript
H5
說到跨平臺,沒人不知道H5。不論是在Mac、Windows、Linux、iOS、Android仍是其餘平臺,只要給一個瀏覽器,連「月球」上它都能跑。css
瀏覽器架構
下面,咱們來看看讓H5如此橫行霸道的瀏覽器的架構:前端

- User Interface 用戶界面:提供用戶與瀏覽器交互
- Browser Engine 瀏覽器引擎:控制渲染引擎與JS解釋器
- Rendering Engine 渲染引擎:負責頁面渲染
- JavaScript Interpreter JS解釋器:執行JS代碼,輸出結果給渲染引擎
- Networking 網絡工做組:處理網絡請求
- UI Backend UI後端:繪製窗口小部件
- Data Storage 數據存儲:管理用戶數據
瀏覽器由以上7個部分組成,而「渲染引擎」是性能優化的重中之重,一塊兒瞭解其中的渲染原理。java
渲染引擎原理
不一樣的瀏覽器內核不一樣,渲染過程會不太同樣,但主要流程仍是一致的。android

分爲下面6步驟:ios
- HTML解析出DOM Tree
- CSS解析出CSSOM
- DOM Tree與CSSOM關聯生成Render Tree
- Layout 根據Render Tree計算每一個節點的尺寸、位置
- Painting 根據計算好的信息繪製整個頁面的像素信息
- Composite 將多個複合圖層發送給GPU,GPU會將各層合成,而後顯示在屏幕上。
從以上6步,咱們能夠總結渲染優化的要點:git
- Layout在瀏覽器渲染過程當中比較耗時,應儘量避免重排的產生
- 複合圖層佔用內存比重很是高,可採用減少複合圖層進行優化
以上就是瀏覽器端的內容。但H5做爲跨平臺技術的載體,是如何與不一樣平臺的App進行交互的呢?這時候JSBridge就該出場了。github
JSBridge原理
JSBridge,顧名思義,是JS和Native之間的橋樑,用來進行JS和Native之間的通訊。web

通訊分爲如下兩個維度:小程序
那麼App內加載H5的過程是什麼樣的呢?
App打開H5過程

打開H5分爲4個階段:
- 交互無反饋
- 打開頁面 白屏
- 請求API,處於loading狀態
- 出現數據,正常展示
這四步,對應的過程如上圖因此,咱們能夠針對性的作性能優化。
優缺點分析
下面,咱們進行H5的優缺點分析:
優勢
- 跨平臺:只要有瀏覽器,任何平臺均可以訪問
- 開發成本低:生態成熟,學習成本低,調試方便
- 迭代速度快:無需審覈,及時響應,用戶可毫無感知使用最新版
缺點
- 性能問題:在反應速度、流暢度、動畫方面遠不及原生
- 功能問題:對攝像頭、陀螺儀、麥克風等硬件支持較差
雖然H5目前還存在不足,但隨着PWA、WebAssembly等技術的進步,相信H5在將來可以獲得越來也好的發展。
小程序
2018年是微信小程序飛速發展的一年,19年,各大廠商快速跟進,已經有了很大的影響力。下面,咱們以微信小程序爲例,分析小程序的技術架構。

小程序跟H5同樣,也是基於Webview實現。但它包含View視圖層、App Service邏輯層兩部分,分別獨立運行在各自的WebView線程中。
View
能夠理解爲h5的頁面,提供UI渲染。由WAWebview.js來提供底層的功能,具體以下:
- 消息通訊封裝爲WeixinJSBridge
- 日誌組件Reporter封裝
- wx api(UI相關)
- 小程序組件實現和註冊
- VirtualDOM,Diff和Render UI實現
- 頁面事件觸發
每一個窗口都有一個獨立的WebView進程,所以微信限制不能打開超過5個層級的頁面來保障用戶體驗。
App Service
提供邏輯處理、數據請求、接口調用。由WAService.js來提供底層的功能,具體以下:
- 日誌組件Reporter封裝
- wx api
- App,Page,getApp,getCurrentPages等全局方法
- AMD模塊規範的實現
運行環境:
- iOS:JavaScriptCore
- Andriod:X5內核,基於Mobile Chrome 53/57
- DevTool:nwjs Chrome 內核
僅有一個WebView進程
View & App Service通訊
視圖層和邏輯層經過系統層的JSBridage進行通訊,邏輯層把數據變化通知到視圖層,觸發視圖層頁面更新,視圖層將觸發的事件通知到邏輯層進行業務處理。
優缺點分析
優勢
- 預加載WebView,準備新頁面渲染
- View層和邏輯層分離,經過數據驅動,不直接操做DOM
- 使用Virtual DOM,進行局部更新
- 組件化開發
缺點
- 仍使用WebView渲染,並不是原生渲染,體驗不佳
- 不能運行在非微信環境內
- 沒有window、document對象,不能使用基於瀏覽器的JS庫
- 不能靈活操做 DOM,沒法實現較爲複雜的效果
- 頁面大小、打開頁面數量都受到限制
既然WebView性能不佳,那有沒有更好的方案呢?下面咱們看看React Native。
React Native

RN的理念是在不一樣平臺上編寫基於React的代碼,實現Learn once, write anywhere。
Virtual DOM在內存中,能夠經過不一樣的渲染引擎生成不一樣平臺下的UI,JS和Native之間經過Bridge通訊
React Native 工做原理

在 React 框架中,JSX 源碼經過 React 框架最終渲染到了瀏覽器的真實 DOM 中,而在 React Native 框架中,JSX 源碼經過 React Native 框架編譯後,與Native原生的UI組件進行映射,用原生代替DOM元素來渲染,在UI渲染上很是接近Native App。
### React Native 與Native平臺通訊

- React Native用JavaScriptCore做爲JS的解析引擎,在Android上,須要應用本身附帶JavaScriptCore,iOS上JavaScriptCore屬於系統的一部分,不須要應用附帶。
- 用Bridge將JS和原生Native Code鏈接起來。Native和 JavaScript 兩端都保存了一份配置表,裏面標記了全部Native暴露給 JavaScript 的模塊和方法。交互經過傳遞 ModuleId、MethodId 和 Arguments 進行。
優缺點分析
優勢
- 垮平臺開發:相比原生的ios 和 android app各自維護一套業務邏輯大同小異的代碼,React Native 只須要同一套javascript 代碼就能夠運行於ios 和 android 兩個平臺,在開發、測試和維護的成本上要低不少。
- 快速編譯:相比Xcode中原生代碼須要較長時間的編譯,React Native 採用熱加載的即時編譯方式,使得App UI的開發體驗獲得改善,幾乎作到了和網頁開發同樣隨時更改,隨時可見的效果。
- 快速發佈:React Native 能夠經過 JSBundle 即時更新 App。相比原來冗長的審覈和上傳過程,發佈和測試新功能的效率大幅提升。
- 渲染和佈局更高效:React Native擺脫了WebView的交互和性能問題,同時能夠直接套用網頁開發中的css佈局機制。脫了 autolayout 和 frame 佈局中繁瑣的數學計算,更加直接簡便。
缺點
- 動畫性能差:React Native 在動畫效率和性能的支持還存在一些問題,性能上不如原生Api。
- 不能徹底屏蔽原平生臺:就目前的React Native 官方文檔中能夠發現仍有部分組件和API都區分了Android 和 IOS 版本,即使是共享組件,也會有平臺獨享的函數。也就是說仍不能真正實現嚴格意義上的「一套代碼,多平臺使用」。另外,由於仍對ios 和android的原生細節有所依賴,因此須要開發者若不瞭解原平生臺,可能會遇到一些坑。
- 生態不完善:缺少不少基本控件,第三方開源質量參差不齊
展望將來
雖然RN還存在不足,但RN新版本已經作了以下改進,而且RN團隊也在積極準備大版本重構,可否成爲開發者們所信賴的跨平臺方案,讓咱們拭目以待。
- 改變線程模式。UI 更新再也不同時須要在三個不一樣的線程上觸發執行,而是能夠在任意線程上同步調用 JavaScript 進行優先更新,同時將低優先級工做推出主線程,以便保持對 UI 的響應。
- 引入異步渲染能力。容許多個渲染並簡化異步數據處理。
- 簡化 JSBridge,讓它更快、更輕量。
既然React Native在渲染方面還擺脫不了原生,那有沒有一種方案是直接操控GPU,自制引擎渲染呢,咱們終於迎來了Flutter!
Flutter
Flutter是Google開發的一套全新的跨平臺、開源UI框架,支持iOS、Android系統開發,而且是將來新操做系統Fuchsia的默認開發套件。渲染引擎依靠跨平臺的Skia圖形庫來實現,依賴系統的只有圖形繪製相關的接口,能夠在最大程度上保證不一樣平臺、不一樣設備的體驗一致性,邏輯處理使用支持AOT的Dart語言,執行效率也比JavaScript高得多。
Flutter架構原理

Dart優點
不少人會好奇,爲何Flutter要用Dart,而不是用JavaScript開發,這裏列下Dart的優點
- Dart 的性能更好。Dart在 JIT模式下,速度與 JavaScript基本持平。可是 Dart支持 AOT,當以 AOT模式運行時,JavaScript便遠遠追不上了。速度的提高對高幀率下的視圖數據計算頗有幫助。
- Native Binding。在 Android上,v8的 Native Binding能夠很好地實現,可是 iOS上的 JavaScriptCore不能夠,因此若是使用 JavaScript,Flutter 基礎框架的代碼模式就很難統一了。而 Dart的 Native Binding能夠很好地經過 Dart Lib實現。
- Fuchsia OS。Fuchsia OS內置的應用瀏覽器就是使用 Dart語言做爲 App的開發語言。
優缺點分析
優勢
- 性能強大:在兩個平臺上重寫了各自的UIKit,對接到平臺底層,減小UI層的多層轉換,UI性能能夠比肩原生
- 優秀的語言特性:參考上面Dart優點分析
- 路由設計優秀:Flutter的路由傳值很是方便,push一個路由,會返回一個Future對象(也就是Promise對象),使用await或者.then就能夠在目標路由pop,回到當前頁面時收到返回值。
缺點
- 優勢即缺點,Dart 語言的生態小,精通成本比較高
- UI控件API設計不佳
- 與原生融合障礙不少,不利於漸進式升級
總結
移動互聯網的普及和快速發展,跨平臺技術風起雲涌,這也是技術發展過程當中的必經之路,等浪潮退去,才知道誰在裸泳。我我的更看好H5或類H5方案,給它一個瀏覽器,連「月球」都能跑,這纔是真正的跨平臺,其餘都是浮雲。
廣而告之
本文發佈於薄荷前端週刊,歡迎Watch & Star ★,轉載請註明出處。
歡迎討論,點個贊再走吧 。◕‿◕。 ~