「得移動端者得天下」,移動端取代PC端,成為了互聯網行業最大的流量分發入口,因此不少公司制定了「移動優先」的發展策略。

為了幫助讀者更好地學習WEEX,本節將對React Native、Weex和Flutter等主流的跨平台方案進行簡單的介紹和對比。

React Native

React Native (簡稱RN)是Facebook於2015年4月開源的跨平台移動應用開發框架,是Facebook早先開源的React框架在原生移動應用平台的衍生產物,目前主要支持iOS和安卓兩大平台。

RN使用Javascript語言來開發移動應用,但UI渲染、網路請求等均由原生端實現。具體來說,開發者編寫的Javascript代碼,通過中間層轉化為原生控制項後再執行,因此熟悉Web前端開發的技術人員只需很少的學習就可以進入移動應用開發領域,並可以在不犧牲用戶體驗的前提下提高開發效率。

作為一個跨平台技術框架,RN從上到下可以分為Javascript層、C++層和Native層。其中,C++層主要用於實現動態連結庫(.so),作為中間適配層橋接,實現js端與原生端的雙向通信交互,如下圖所示是RN在Android平台上的通信原理圖。

在RN的三層架構中,最核心的就是中間的C++層,C++層最核心的功能就是封裝JavaScriptCore,用於執行對js的解析。同時,原生端提供的各種Native Module(如網路請求,ViewGroup控制項模塊)和JS端提供的各種JS Module(如JS EventEmiter模塊)都會在C++實現的so文件中保存起來,最終通過C++層中的保存的映射實現兩端的交互。

在RN開發過程中,大多數情況下開發人員並不需要需要了解RN框架的具體細節,只需要專註JS端的邏輯代碼實現即可。但是需要注意的是,由於js代碼是運行在獨立的JS線程中,所以在js中不能處理耗時的操作,如fetch、圖片載入和數據持久化等操作。

最終,JS代碼會被打包成一個bundle文件並自動添加到應用程序的資源目錄下,而應用程序最終載入的也是打包後的bundle文件。RN的打包腳本位於「/node_modules/react-native/local-cli」目錄下,打包後通過metro模塊壓縮成bundle文件,而bundle文件只包含打包js的代碼,並不包含圖片、多媒體等靜態資源,而打包後的靜態資源會是被拷貝到對應的平台資源文件夾中。

總的來說,RN使用Javascript來編寫應用程序,然後調用原生組件執行頁面渲染操作,在提高了開發效率的同時又保留了Native的用戶體驗。並且,伴隨著Facebook重構RN工作的完成,RN也將變得更快、更輕量、性能更好。

Weex

作為一套前端跨平台技術框架,Weex建立了一套源碼轉換以及Native與Js通信的機制。Weex表面上是一個客戶端框架,但實際上它串聯起了從本地開發、雲端部署到分發的整個鏈路。 具體來說,在開發階段編寫一個.we文件,然後使用Weex提供的weex-toolkit轉換工具將.we文件轉換為JS bundle,並將生成的JS bundle上傳部署到雲端,最後通過網路請求或預下發的方式載入至用戶的移動應用客戶端。當集成了Weex SDK的客戶端接收到JS bundle文件後,調用本地的JavaScript引擎執行環境執行相應的JS bundle,並將執行過程中產生的各種命令發送到native端進行界面渲染、數據存儲、網路通信以及用戶交互響應。

由上圖可知,Weex框架中最核心的部分就是JavaScript Runtime。具體來說,當需要執行渲染操作時,在iOS環境下選擇基於JavaScriptCore內核的iOS系統提供的JSContext,在Android環境下使用基於JavaScriptCore內核的JavaScript引擎。

當JS bundle從伺服器下載完成之後,Weex的Android、iOS和H5會運行一個JavaScript引擎來執行JS bundle,同時向各終端的渲染層發送渲染指令,並調度客戶端的渲染引擎實現視圖渲染、事件綁定和處理用戶交互等操作。 由於Android、iOS和H5等終端最終使用的是native渲染引擎,也就是說使用同一套代碼在不同終端上展示的樣式是相同的,並且Weex使用native引擎渲染的是native組件,所以在性能上比傳統的WebView方案要好很多。

當然,儘管Weex已經提供了開發者所需要的最常用的組件和模塊,但面對豐富多樣的移動應用研發需求,這些常用基礎組件還是遠遠不能滿足開發的需要,因此Weex提供了靈活自由的擴展能力,開發者可以根據自身的情況定製屬於自己客戶端的組件和模塊,從而豐富Weex生態。

Flutter

Flutter是Google開源的移動跨平台框架,其歷史最早可以追溯到2015年的Sky項目,該項目可以同時運行在Android、iOS和fuchsia等包含Dart虛擬機的平台上,並且性能無限接近原生。相較於RN和Weex使用Javascript作為編程語言與使用平台自身引擎渲染界面不同,Flutter直接選擇2D繪圖引擎庫skia來渲染界面。

如上圖所示,Flutter框架主要由Framework和Engine層組成,而我們基於Framework開發App最終會運行在Engine上。其中,Engine是Flutter提供的獨立虛擬機,正是由於它的存在Flutter程序才能運行在不同的平台上,實現跨平台運行的能力。 與RN和Weex使用原生控制項渲染界面不同,Flutter並不需要使用原生控制項來渲染界面,而是使用Engine來繪製Widget(Flutter顯示單元),並且Dart代碼會通過AOT編譯為平台的原生代碼,實現與平台的直接通信,不需要JS引擎的橋接,也不需要原生平台的Dalvik虛擬機,如圖1-5所示。 同時,Flutter的Widget採用現代響應式框架來構建,而Widget是不可變的,僅支持一幀,並且每一幀上的內容不能直接更新,需要通過Widget的狀態來間接更新。在Flutter中,無狀態和有狀態Widget的核心特性是相同的,視圖的每一幀Flutter都會重新構建,通過State對象Flutter就可以跨幀存儲狀態數據並恢復它。

總的來說,Flutter是目前跨平台開發中最好的方案,它以一套代碼即可生成Android和iOS平台兩種應用,很大程度上減少了App開發和維護的成本,同時Dart語言強大的性能表現和豐富的特性,也使得跨平台開發變得更加便利。而不足的是,Flutter還處於Alpha階段,許多功能還不是特別完善,而全新的Dart語言也帶來了學習上的成本,如果想要完全替代Android和iOS開發還有比較長的路要走。

PWA

PWA,全稱Progressive Web App,是Google在2015年提出漸進式的網頁技術。PWA結合了一系列的現代Web技術,並使用多種技術來增強Web App的功能,最終可以讓網頁應用呈現和原生應用相似的體驗。

相比於傳統的網頁技術,漸進式Web技術是可以橫跨Web技術及Native APP開發的技術解決方案,具有可靠、快速且可參與等諸多特點。

具體來說,當用戶從手機主屏幕啟動時,不用考慮網路的狀態就可以立刻載入出PWA。並且,相比傳統的網頁載入速度,PWA的載入速度是非常快的,因為PWA使用了Service Worker 等先進技術。除此之外,PWA還可以被添加在用戶的主屏幕上,不用從應用商店進行下載即可通過網路應用程序Manifest file提供類似於APP的使用體驗。

作為一種全新Web技術方案,PWA的正常工作需要一些重要的技術組件,它們協同工作並為傳統的Web應用程序注入活力,如圖1-8所示。

其中,Service Worker表示離線緩存文件,其本質是Web應用程序與瀏覽器之間的代理伺服器,可以在網路可用時作為瀏覽器和網路間的代理,也可以在離線或者網路極差的環境下使用離線的緩衝文件。

Manifest則是W3C一個技術規範,它定義了基於JSON的清單,為開發人員提供一個放置與Web應用程序關聯的元數據的集中地點。Manifest是PWA 開發中的重要一環,它為開發人員控制應用程序提供了可能。

目前,漸進式Web應用還處於起步階段,使用的廠商也是諸如Twitter、淘寶、微博等大平台。不過,PWA作為Google主推的一項技術標準,Edge、Safari和FireFox等主流瀏覽器也都開始支持漸進式Web應用。因此,可以預見的是,PWA必將成為繼移動之後的又一革命性技術方案。

對比

在當前諸多的跨平台方案中,RN、Weex和Flutter無疑是最優秀的。而從不同的細節來看,三大跨平台框架又有各自的優點和缺點,可以通過表1-1來查看。 | 對比類型 | React Native | Weex |Flutter| |--|--|--|--|--| | 支持平台 | Android/IOS | Android/IOS/Web | Android/IOS| | 實現技術 | JavaScript | JavaScript | 原生編碼/渲染| | 引擎 | JS V8 | JSCore | Flutter Engine|

| 編程語言 | React | Vue |Dart|

| bundle包大小 | 單一、較大 | 較小、多頁面 |不需要| | 框架程度 | 較重 | 較輕 |重 | | 社區 | 活躍、FB維護 | 不活躍 |活躍 |

如上表所示,RN、Weex採用的技術方案大體相同,它們都使用JavaScript作為編程語言,然後通過中間層轉換為原生的組件後再利用Native渲染引擎執行渲染操作。而Flutter直接使用skia來渲染視圖,而Flutter Widget則使用現代響應式框架來構建,和平台沒有直接的關係。就目前跨平台技術來看,JavaScript在跨平台開發中可謂佔據半壁江山,大有「一統天下」的趨勢。 從性能方面來說,Flutter的性能理論上是最好的,RN和Weex次之,並且都好於傳統的WebView方案。但從目前的實際應用來看卻並沒有太大的差距,特別是和0.5.0版本以上的RN對比性能體驗上差異並不明顯。 而從社群和社區的活躍來看,RN和Flutter無疑是最活躍的,RN經過4年多的發展已經成長為跨平台開發的實際領導者,並擁有各類豐富的第三方庫和開發群體。Flutter作為最近才火起來的跨平台技術方案,不過目前還處在beta階段,商用的實例也很少,不過應該看到google的號召力一直是很強,未來究竟如何發展讓我們拭目以待。

示例

eros-yanxuan

簡介

eros-yanxuan 是基於 eros 開發的Weex項目,部分頁面參考了項目網易嚴選 weex 版本,歡迎star或fork。

  • eros 文檔
  • eros github

運行

確保你本地已經集成了 eros 開發所需的環境。

clone 項目到本地:

$ git clone https://github.com/xiangzhihong/eros-yanxuan.git

進入目錄,下載前端所需的依賴:

$ cd eros-yanxuan
$ npm install

iOS SDK

打開platforms目錄下的WeexEros項目,在WeexEros中使用pod添加依賴。

$ cd platforms/ios/WeexEros
$ pod update // 下載 iOS 依賴
$ open WeexEros.xcworkspace // 自動打開項目

選中模擬器,點擊綠色箭頭運行 app 即可。

Android

對於Android工程來說,使用Android Studio打開platforms目錄下的WeexFrameworkWrapper的Android工程,然後使用install.sh安裝Android工程的需要依賴包nexus和wxframework。

具體可以參考自行導入項目,便可運行起來。

運行

  • 項目根目錄下運行 eros dev
  • 關閉調試,攔截器,打開熱更新
  • 重新 build app

效果

Question

運行過程中出現問題在以下地址解決方法,如果沒有找到,可以參考eros快速入門新建一個Weex工程,然後將src和配置文件的代碼拷貝過去。 如果還有問題,請加群:515980159

  • 移動跨平台技術總結
  • Weex快速上手
  • eros快速入門
  • eros issue
  • eros Q&A

推薦閱讀:

相关文章