动态

详情 返回 返回

年終盤點跨平台技術優劣勢對比(Hybrid、RN、Weex、Flutter) - 动态 详情

跨平台技術發展的三個階段

  • 第一階段是混合開發的web容器時代

    • 為了解決原生開發的高成本、低效率,出現了Hybrid混合開發
    • 原生中嵌入依託於瀏覽器的WebView
    • Web瀏覽器中可以實現的需求在WebView中基本都可以實現
    • 但是Web最大的問題是,它的性能和體驗與原生開發存在肉眼可感知的差異
    • 因此並不適用於對性能和用户體驗要求較高的場景
  • 第二階段是以RN和Weex為代表的泛web容器時代

    • RN對Web標準進行了功能裁剪
    • 用户體驗更接近於原生了
    • 由於進行了功能裁剪,所以RN對業務的支持能力還不到瀏覽器的5%
    • 因此僅適用於中低複雜度的低交互類頁面。面對稍微複雜一點兒的交互和動畫需求,都需要通過調用原生代碼去擴展才能實現
  • 第三階段是以Flutter為代表的自繪引擎時代

    • Flutter是構建Google物聯網操作系統Fuchsia的SDK
    • 它使用Dart語言開發APP
    • 一套代碼可以同時運行在iOS和Android平台上
    • Flutter採用自帶的Native渲染引擎渲染視圖,它是自己完成了組件渲染的閉環
    • 而RN、Weex之類的框架,只是通過JavaScript虛擬機擴展調用系統組件,最後是由Android或者iOS系統來完成組件的渲染

下面來看一下幾類型的混合開發APP:

Web APP框架

ionic

Ionic框架是基於Web技術應用HTML、CSS以及Java技術進行智能設備APP開發的框架,Ionic框架是用來開發混合模式的移動APP開發框架;

優勢

  • 全套的UI組件
    Ionic框架很注重外觀的體驗,所以它提供了很多UI組件幫助開發者開發APP,比如:下拉刷新、標籤等。界面美觀,開發者能夠很快的上手,開發的APP都很實用。
  • 代碼容易維護
    Ionic框架是基於AngularJS,也就支持AngularJS的特點,遵循標準的代碼,維護代碼就很容易,能夠完美融合AngularJS
  • 支持跨平台
    可以在主流的Android操作系統和ios操作系統上運行,或者其他的操作系統也可以支持
  • 很多強大的命令行
  • 強大的社區、框架適用範圍廣
    能夠編譯成各個平台的應用程序

劣勢

  • 內存佔用高
  • 不適合做遊戲類型app
  • web技術無法解決一切問題,對於比較耗性能的地方無法利用native的思維實現優勢互補,如高體驗的交互,動畫等

Cordova

Cordova提供了一組設備相關的API;通過這組API,移動應用能夠以JavaScript訪問原生的設備功能,如攝像頭、麥克風等;Cordova還提供了一組統一的JavaScript類庫,以及為這些類庫所用的設備相關的原生後台代碼;Cordova支持如下移動操作系統:iOS, Android,ubuntu phone os, Blackberry, Windows Phone, Palm WebOS, Bada 和 Symbian。

通信

  • 通信原理

    1. 保存Cordova_plugin.js的 插件文件名字和地址
    2. 插件的API呼出時,通過調用Cordova的exec模塊將API的參數保存在CommandQueue的隊列中。 CALLBACK則保存在JS側的callbacks map裏面
    3. 添加一個空的iframe,iframe的src則指向gap://ready
    4. 3的iframe的src設置以後,NATIVE側UIWebviewDelegate#shouldStartLoadWithRequest則被呼出來
    5. Webview的Delegatet判斷gap://ready的情況下,則執行commandDelegate的處理
    6. commandDelegate則從JS側取出API的參數,內部實現則是通過 UIWebview#stringByEvaluatingJavaScriptFromString的返回值 取得CommandQueue裏面的參數轉換成JSON數據
    7. 根據6的插件,執行NATIVE定義的插件實例
    8. 插件中,有CALLBACK的情況下,成功失敗的結果通過UIWebview#stringByEvaluatingJavaScriptFromString執行JS,JS端則根據傳過來的CALLBACKID,從callbacks map取出回調函數並執行
  • 通信方式

    • iframe的方法(默認)
    • xmlHttpRequest的方法(iOS5.x版本因為 -webkit-scroll的IFRAME有BUG,則推薦使用)
  • 插件導入流程

    • Native

      - APP啓動,MainViewController初始化之時,queue和command的DELEGATE初期化
      - config.xml文件解析,插件名設置到數組,插件文件和插件名設置到pluginMap,屬性設置到setting
      - 在Webview類裏面,加載index.html,index.html裏面加載cordova.js、開始初期化
      
    • JS

      - 加載cordova.js時、內部的事件設置模塊,NATIVE交互模塊,初期化模塊,插件加載
      - 插件模塊是cordova_plugins.js文件定義的插件文件地址,文件名保存的MAP
      - deviceready事件發佈後,插件的API可以使用了
      - 插件API執行後,模塊MAP將插件文件加載,執行exec函數
      - 在index.html裏面添加一個空的iframe、指定src=gap://ready,通知到Nativie
      

優勢

  • iOS和Android基本上可以共用代碼;
  • 純web思維,開發速度快, 簡單方便,一次編碼,到處運行;
  • 如果熟悉web開發,文檔很全, 系統級支持封裝較好,所有UI組件都是有html模擬,可以統一 使用;
  • 可實現在線更新,允許動態加載web js;
  • 文檔多,開發者多,遇到問題容易解決,技術成熟;

劣勢

  • 佔用內存高一些;
  • 不適合做遊戲類型app;
  • web技術午無法解決一 切問題,對於比較耗能的地方無法利用native的思維實現優勢互 補,如高體驗的交互,動畫等。

Hybrid APP(Webview)

利用 安卓和 iOS 上的 webview 容器,APP 能夠執行 html、css 和 js 腳本,展示 web 頁面。如果需要原生功能就添加 bridge 供 java 調用。具有開發效率高、跨平台、支持動態發佈等特點,它是目前應用最廣泛最成熟的一種方案;

Webview通信

  • 假跳轉的請求攔截(不建議)

    • 假跳轉的請求攔截 就是由網頁發出一條新的跳轉請求,跳轉的目的地是一個非法的壓根就不存在的地址
    • 比如:wbcst://testhost/action?params=xxx
    • 模擬http協議網絡請求 scheme://host/action?params
    • 客户端會無差別攔截所有請求,真正的url地址應該照常放過,只有協議域名匹配的url地址才應該被客户端攔截
    • JS調用方式

      1. a標籤跳轉
      2. location.href跳轉
      3. iframe跳轉
    • 不建議使用,android系統對url參數做了字節限制,無法進行大數據的通信
  • 彈窗攔截(不建議)

    • alert

      • 彈出個提示框,只能點確認無回調
    • confirm

      • 彈出個確認框(確認,取消),可以回調
    • prompt

      • 彈出個輸入框,讓用户輸入東西,可以回調
    • 不建議使用,會無差別的攔截所有前端的window彈窗
  • JS上下文注入(推薦)

    • iOS

      • WKWebView scriptMessageHandler注入
    • android

      • addJavascriptInterface注入
    • 特點

      • 不通過任何攔截的辦法,而是直接將一個native對象(or函數)注入到JS裏面,可以由web的js代碼直接調用,直接操作

WebView 渲染引擎設計的上的缺陷

  • JS Execute,Layout, Paint 都在MainThread ,無法並行化。
  • JS 的性能趕不上 Native Tookit 的 Java Dart Object-C 等編譯型語言,執行復雜邏輯時會卡頓。
  • 渲染流水線非常長,導致瀏覽器對合成器動畫和非合成器動畫區分對待,非合成器動畫性能不佳。
  • OpenGL 設計上是推薦單線程模型,一個 Context 同時只能運行一個線程使用。 GPU Thread 運行在單獨 GPU 進程, Render 進程無法訪問 GPU 進程的 OpenGL Context ,兩個進程無法 Texture 共享資源。 Render 進程只能輸出 Bitmap/Command Buffer 通過 IPC 傳遞給 GPU 進程,無法直接在 GPU 進程的 Open GL Context 做直接光柵化,難以充分發揮現代 GPU 的性能。
  • 光柵化是異步進行的,進行慣性滾動時,會出現白屏,這個是 Webview 始終無法避免的問題。
  • 設備平台眾多,需要兼容CPU渲染,無法進行 All In GPU 的設計。

優勢

  • 跨平台
  • 開發週期短、成本低
  • 用户體驗良好
  • 可以即時修復bug、動態發版

劣勢

  • 仿原生iOS效果複雜
  • 機型兼容性

ReactNative/Weex跨平台技術

這種技術最大化的複用前端的生態和 Native 的生態體系,把 Native View 的高性能組件積累輸出給前端的技術體系。此方案和瀏覽器的最大區別在於 Script 的執行和 Native View 渲染體系。

ReactNative

img

通信流程(OC)

  • ①js調用OC模塊暴露出來的方法
  • ②把調用方法分解為ModuleName、MethodName、arguments,在丟給MessageQueue處理
  • ③把js的callback函數緩存在MessageQueue的一個成員變量裏面,同時生成一個CallbackID來代表callback;在通過保存在MessageQueue的模塊配置表把ModuleName、MethodName轉成ModuleID、MethodID
  • ④把ModuleID、MethodID、CallbackID和其他參數傳給OC(JavaScriptCore)
  • ⑤OC接到消息,通過模塊配置表拿到對於的模塊和方法
  • ⑥RCTModuleMethod對js傳過來的參數進行處理
  • ⑦OC模塊方法執行完,執行block回調
  • ⑧調用第6步中RCTModuleMethod生成的block
  • ⑨block帶着CallbackID和block傳過來的參數去掉用js裏的MessageQueue方法invokeCallbackAndReturnFlushedQueue
  • ⑩MessageQueue通過CallbackID找到相應的js的callback方法
  • ⑪調用callback方法,並把OC帶過來的參數一起傳過去完成回調

優勢

雖然不能做到一次編碼到處運行,但是基本上即使是兩套代碼, 也是相同的jsx語法, 使用js進行開發。用户體驗高於html, 開發效率較高

Flexbox佈局據説比native的自適應佈局更加簡單高效

劣勢

對開發人員要求較高,不是懂點web技術就行的,當官方封裝的 控件、API無法滿足需 求時就必然需要懂一些native的東西去 擴展,擴展性仍然遠遠不如web,也遠遠不如直 接寫Native Code。

Weex

img

實現原理

Weex 對外通過 Rax 和 Vue 前端框架進行功能輸出,前端框架下有一層 JS Framework 來實現 dom 的功能。 WeexCore 負責基礎的 Flex Layout ,然後通過 Component 分別對接到 Android/iOS 的 Platform Native View 體系。

優勢

  • Android Native 採用更輕量級的渲染流水線,能更快更高效的的響應事件;
  • RenderThread 直接操作 OpenGLContext ,進行 Direct GPU Raster ,充分發揮現代 GPU 的特性,提供高性能渲染和流暢的體驗;
  • 部分耗時操作,如 Bitmap 上傳 Texture , TextureThread 上傳到 Share Open GL Context 中, Texture 完成後通知主線程進行繪製,通過 Share Open GL Context 與主線程共享 Texture 等資源。 WebView 只能在 Render Process 內部進行 Texture 的共享, RenderProcess 無法與 GPU Process 共享 Texture 等資源;
  • Android Native 有 RecycleView ViewPager 等高級組件,每個高級組件都做了性能的最佳實踐;瀏覽器上的高級組件只能通過 JS 模擬實現,優化定製效率低;
  • 瀏覽器流水線設計複雜,需要考慮到 PC 、手機、嵌入式設備等多種複雜的環境,不少設備上木有 GPU ,只能進行 CPU 渲染。無法像 Android Native 體系一樣進行 All In GPU 的體系設計,全面發揮現代 GPU 的性能。

劣勢

Weex 體系充分將 Native 的 View 體系輸出到前端體系中,在進行 Android/iOS Native View 的封裝過程中,存在不少難以逾越的障礙

Flutter自繪引擎

Flutter是Google發佈的一個用於創建跨平台、高性能移動應用的框架。Flutter和QT mobile一樣,都沒有使用原生控件,相反都實現了一個自繪引擎,使用自身的佈局、繪製系統

框架

圖1-1

基礎架構主要分為三個部分:

  • Framework

    • 純 Dart實現的 SDK,類似於 React在 JavaScript中的作用
    • 它實現了一套基礎庫, 用於處理動畫、繪圖和手勢
    • 基於繪圖封裝了一套 UI組件庫
    • 根據 Material 和Cupertino兩種視覺風格區分開來
  • Engine

    • 純 C++實現的 SDK
    • 包括

      • Skia引擎
      • Dart運行時
      • 文字排版引擎等
    • 它是 Dart的一個運行時,它可以以 JIT 或者 AOT的模式運行 Dart代碼
    • 這個運行時還控制着 VSync信號的傳遞、GPU數據的填充等,並且還負責把客户端的事件傳遞到運行時中的代碼
  • Embedder

    • Embedder是操作系統適配層
    • 實現了

      • 渲染Surface設置
      • 線程設置
      • 平台插件等平台相關特性的適配

渲染流程

image-20210126154129830

  • GPU的VSync信號同步給到UI線程
  • UI線程使用Dart來構建抽象的視圖結構(這裏是Framework層的工作)
  • 繪製好的抽象視圖數據結構在GPU線程中進行圖層合成(在Flutter Engine層的工作)
  • 然後提供給Skia引擎渲染為GPU數據,最後通過OpenGL或者 Vulkan提供給 GPU

優勢

高生產效率。一套代碼可以開發出Android和iOS應用;Dart語 言優越性,使得同樣的 功能只需要很少的代碼;迭代更加方便, hot reload功能;

創建優雅的、高度可定製的用户界面。Flutter內置了對Material Design和Cupertino(iOS-favor)的UI組件庫;提供了可定製 的UI組件,不再受制於OEM控件的限制;

藉助可移植的GPU加速的渲染引擎以及高性能本地ARM代碼運行 時以達到跨平台的高質量用户體驗。

劣勢

Flutter採用Dart語言開發,屬於小眾語言,需要一切都要重新 學習。

橫向對比

對比內容 ReactNative weex Flutter Hybrid
平台實現 JavaScript JavaScript 原生編碼 H5
引擎 JSCore JS V8 Flutter Engine Webview
核心語言 React Vue Dart JavaScript
打包bundle文件 默認單一文件比較大(可拆包) 較小,多頁面多文件 不需要 前端JS、CSS一般CDN引用
跨平台 中上
熱更新 暫無方案
性能 中上

Add a new 评论

Some HTML is okay.