APP常用跨端技術棧深入分析

京東雲發表於2022-07-22

導讀


本文主要針對常用跨端技術Flutter、ReactNative、Weex、H5,從技術特點、基本架構、編譯原理、基本渲染流程等進行梳理分析;以及一些常見效能問題如何最佳化解決,然後如何進行技術選型或在進行業務開發時選擇不同技術棧的邏輯是什麼。


01

背景

在今年的敏捷團隊建設中,我透過Suite執行器實現了一鍵自動化單元測試。Juint除了Suite執行器還有哪些執行器呢?由此我的Runner探索之旅開始了!

隨著技術的發展,產生了越來越多的端,如Android、iOS、Mac、Windows、Web、Fuchsia OS、鴻蒙等,而隨著公司業務的發展,出現了越來越多的業務場景;作為APP開發人員,在日常工作中難免會碰到以下問題,如:1、UI設計師在進行UI審查時、測試同學在迴歸測試過程中、業務方在使用過程中,多少會發現端與端存在著差異,影響使用者體驗;2、同樣的業務、同樣的功能在不同的端上,需要每端投入資源去開發實現。而移動網際網路的發展已經處於晚期,領導們越來越關心投入產出。

與此同時,出現了一些跨端的技術解決方案,可以實現一套程式碼在多端執行,解決業務發展上的痛點,如Flutter、ReactNative、Weex、H5(注:小程式和其它基於DSL的方案暫不在本文討論範圍)。然後對一些常用APP進行了對比分析,結論和預期一致,大部分都在使用跨端技術;Flutter和ReactNative使用率較高,Weex使用率相對低一些,H5基本都在使用,使用多種跨端技術框架是一種常態。那麼,它們都有哪些特點呢?

02

四種技術棧特點介紹

理解,首先 MCube 會依據模板快取狀態判斷是否需要網路獲取最新模板,當獲取到模板後進行模板載入,載入階段會將產物轉換為檢視樹的結構,轉換完成後將透過表示式引擎解析表示式並取得正確的值,透過事件解析引擎解析使用者自定義事件並完成事件的繫結,完成解析賦值以及事件繫結後進行檢視的渲染,最終將目標頁面展示到螢幕。

APP常用跨端技術棧深入分析

圖1-技術棧特點

透過圖1,從效能、開發語言、渲染、包大小、社群、支援平臺等方面梳理了它們的主要特點;不由產生幾個問題:為什麼原生和Flutter效能更好?為什麼ReactNative和Weex效能相對較差?為什麼H5頁載入慢?這些效能問題該如何去最佳化,這是需要深入瞭解的問題,下面將從基本的架構、渲染流程、編譯執行原理等一起分析。


03基礎架構介紹

3.1 Flutter基礎架構介紹

ABM是Apple公司提供的iOS應用的分發渠道之一,與App Store平臺不同,ABM是2019年10月才開始在中國區啟動的一套全新的應用分發系統,部分功能和企業賬號類似,旨在為企業提供快速、高效的方式來部署應用到企業擁有的蘋果裝置。ABM與App Store兩個平臺的關鍵區別如下:

APP常用跨端技術棧深入分析

圖2-Flutter基礎架構

Google在2018年釋出了Flutter 1.0,如圖2所示,主要分為Framework層和Engine層;

Framework層:基於Dart實現,主要包括Text、Image、Button、動畫、手勢等各種Widgets,核心基礎類庫io、async、ui等package;基於Framework開發App,其執行在Engine層上,Framework和邏輯層都在基於Dart語言開發,對於開發而言,一切都是Widget,Widget是UI實現的基礎;Engine層:基於C++、C實現;主要包括Skia渲染引擎庫、Dart Runtime、Text文字渲染庫等,而Engine層自帶Skia渲染引擎,以此實現所有端的渲染展示統一,在Engine層適配平臺差異和跨平臺支援,實現更完美的跨端效果;Dart程式碼透過AOT編譯為執行平臺的二進位制程式碼。也就是說Flutter不需要橋接,自己完成從邏輯側和渲染側的所有能力,和原生類似。這也是它效能突出的關鍵所在。另外Android自帶Skia引擎,所以也使得在Android的的編譯產物比iOS更小。除了支援移動端外,還支援Mac OS、Windows等PC端和Web端,在新的Funchsia OS也支援Dart,使用Flutter作為UI框架。

對於Flutter Web,Framework層是公用的,意味著業務層可以使用此層的widgets實現邏輯跨端;但Engine層則不同,需要透過Canvas Render或者 HTML Render對齊Engine的能力。2022年5月Google IO大會發布Flutter 3.0,除了移動端,更好的支援了Mac OS、Linux平臺,也包括其它一系列最佳化和支援,大家可以多關注。


3.2 ReactNative基礎架構介紹

ABM是Apple公司提供的iOS應用的分發渠道之一,與App Store平臺不同,ABM是2019年10月才開始在中國區啟動的一套全新的應用分發系統,部分功能和企業賬號類似,旨在為企業提供快速、高效的方式來部署應用到企業擁有的蘋果裝置。ABM與App Store兩個平臺的關鍵區別如下:

APP常用跨端技術棧深入分析

圖3-ReactNative基礎架構

ReactNative是Facebook於2015年開源,如圖3所示,主要服務於Android和iOS兩端,採用React開發實現邏輯側程式碼(也可應用於前端),採用Redux實現狀態管理,在APP中UI渲染、網路請求、動畫等均由原生側橋接實現;在這裡實際執行過程中,js側的dom會形成一個virtual dom,並透過bridge橋接將此dom結構傳輸到原生側,原生側會解析並對映到原生控制元件,形成原生的dom結構後,再呼叫原生能力進行渲染展示。

2021年ReactNative新版本對底層進行了重構,可以關注一下,如改變執行緒模型,引入非同步渲染能力,允許多個渲染並簡化非同步資料處理,簡化 JSBridge等。

3.3 Weex基礎架構介紹

APP常用跨端技術棧深入分析

圖4-Weex基礎架構

Weex是阿里2016年釋出的跨端框架,如圖4所示,Weex編譯產物js bundle可以部署在服務端,APP載入完即可執行,也可以看出具備動態釋出的能力;和ReactNative類似,Weex在實際執行過程中,js側會形成一個dom,並透過Bridge交由原生側解析,對映到原生控制元件再由原生能力進行渲染;Weex基於JS V8引擎,基於Vue設計,支援Android、iOS、Web三端。


3.4 WebView基礎架構介紹

APP常用跨端技術棧深入分析

圖5-WebView核心基礎架構

WebView核心模組較複雜,如圖5所示,這裡主要介紹WebView架構主要的幾個部分:橋接協議是上層邏輯測與WebView的通訊層,是JS和Native互相通訊的能力層;

WebCore是瀏覽器載入和排版渲染頁面的基礎,主要包括資源載入、HTML解析、CSS解析、DOM解析、排版渲染等,JavaScript引擎是JavaScript解析器,JavaScriptCore是Webkit的JavaScript引擎,V8是Google的Blink的預設引擎;WebKit Ports是WebKit中移植部分,包括網路、字型、圖片解碼、音影片解碼、硬體加速等模組;然後再往下也使用了很多第三方庫,包括2D圖形庫、3D圖形庫、網路庫、儲存庫、音影片庫等;最底層是作業系統,支援Android、iOS、Windows等系統。


3.5 編譯原理分析

Flutter支援Release、Profile、Debug編譯模式。

Release模式即使用AOT預編譯模式,預編譯為機器碼,透過編譯生成對應架構的程式碼,在使用者裝置上直接執行對應的機器碼,執行速度快,執行效能好;此模式關閉了所有除錯工具,只支援真機。對於編譯產物,iOS側主要生成App.framework和Flutter.framework;App.framework為dart程式碼編譯產物,Flutter.framework為引擎編譯產物;Android側主要在lib下增加了libapp.so和libflutter.so,libapp.so為dart程式碼編譯產物,libflutter.so為引擎編譯產物,不同的是在assets下增加了flutter_assets存放引用資原始檔。

Profile模式和Release模式類似,此模式最重要的作用是可以用DevTools來檢測應用的效能,做效能除錯分析。

Debug模式使用JIT即時編譯技術,支援常用的開發除錯功能hot reload,在開發除錯時使用,包括支援的除錯資訊、服務擴充套件、Observatory、DevTools等除錯工具,支援模擬器和真機。iOS側主要生成App.framework和Flutter.framework,在App.framework資料夾裡多了isolate_snapshot_data,kernel_blob.bin,vm_snapshot_data;Android側也同樣多了多了以上檔案,但lib下少了libapp.so檔案。

ReactNative整體分為邏輯側和渲染側,邏輯側基於js引擎,會將基於React寫的程式碼編譯為JavaScript原生程式碼,再編譯生成jsbundle檔案,內建或下發到APP端執行;而渲染側依賴於Android或iOS原生渲染,需要分平臺編譯對應的編譯產物,然後釋出到服務端或內建到APP。

Weex和ReactNative類似,weex會將原始碼編譯為js bundle,這些js bundle可以部署在服務端,APP下載完js bundle後,透過js引擎構建虛擬dom並透過橋接對映到原生dom,由原生渲染引擎進行渲染。

H5:以React和Vue為例,會將以框架開發的程式碼編譯為JavaScript原生程式碼,即然後在瀏覽器或者WebView中執行;核心會先建立連線、載入資源,然後解析、排版佈局、繪製渲染呈現給使用者。


3.6 基本渲染流程對比

APP常用跨端技術棧深入分析

圖6-基本渲染流程對比

簡單分析渲染流程,基於Android和iOS原生開發APP,呼叫Framework框架層實現上層邏輯,經過佈局繪製後直接呼叫系統渲染引擎進行渲染展示;基於Flutter開發APP,會直接呼叫Skia渲染引擎進行渲染展示;不依賴於原生渲染。

基於ReactNative或Weex開發APP則不同,首先業務邏輯是基於React或Weex開發,然後會將js bundle包預置或下載到APP,然後將虛擬dom透過bridge對映到原生控制元件,再呼叫原生渲染引擎進行渲染展示。

基於Hybrid方案開發APP,需要透過React、Vue等前端框架實現,首頁要編譯為JavaScript原生語言,然後透過連結在WebView或瀏覽器載入頁面,關鍵的流程是連線載入、解析、排版、繪製,最後再調渲染引擎進行展示。


透過以上所有分析,可以回答前面提出的問題

為什麼原生和Flutter效能更好?主是都是經過佈局繪製後直接調系統或自帶渲染引擎進行展示。

為什麼ReactNative和Weex效能相對慢?主要是需要下載js bundle包,並把js dom結構解析對映到原生,而下載和預置都比較耗時,並且依賴原生進行渲染(ReactNative新版本升級了基礎架構,據說有較大效能提升,大家也可以關注)。

為什麼H5頁載入慢?主要因為連線和載入比較耗時,這裡佔大部分時間,連線和載入完以後基本就是WebView或瀏覽器本地可以完成的工作,後期最佳化也可以以此為切入點。


04常見主要效能問題最佳化

在實際開發過程中也遇到了一些效能問題,接下來進行簡單介紹。


4.1 如何最佳化Flutter效能?

關鍵最佳化指標:頁面異常率、頁面FPS幀率、頁面載入時長。

頁面異常率(異常發生次數 / 整體頁面 PV 數):透過 runZoned 與 FlutterError 兩個方法,在異常攔截的方法中統計異常的發生次數和堆疊資料。

頁面FPS幀率:如何採集FPS是關鍵,透過window物件註冊onReportTimings回撥,就可以得到整個構建和渲染過程的耗時,然後就可以算出頁面的FPS。

頁面載入時長(頁面可見的時間-頁面建立的時間):頁面可見的時間透過WidgetsBinding的addPostFrameCallback回撥獲取,頁面建立的時間透過頁面初始化方法initState獲取。

將以上資料上傳到監控和效能分析平臺(mPaaS和燭龍),作為後期效能分析和最佳化的參考資料,在開發過程中可透過DevToos效能分析工具、Flutter Inspector分析最佳化效能。按需載入,區域性重新整理也是常用的最佳化手段。其它效能最佳化如佈局載入最佳化、狀態管理最佳化、啟動最佳化-引擎預載入、記憶體最佳化、包大小最佳化等不再詳細介紹。可以多關注Flutter社群,定期升級Flutter版本,會帶來很好的收穫。


4.2 如何最佳化ReactNative載入慢的問題?

一是可以預下載bundle包,減少包載入的時間,開啟頁面直接對映渲染,從而達到更快開啟頁面的目的,當然也可以預置包,需要平衡好包大小和效能;

二是嘗試升級ReactNative最新版本,新版本升級了基礎架構,主要包括執行緒模型,引入了非同步渲染能力,最佳化JSBridge,對效能有明顯提升(作者諮詢過京東mPaaS團隊,也在跟進中)。


4.3 如何最佳化APP中H5載入慢的問題

APP常用跨端技術棧深入分析

圖7-載入H5流程介紹

圖7描述了從WebView初始化到H5頁面最終渲染的整個過程,以及和前面H5基本渲染流程進行分析。耗時環節的主要有兩點,一是WebView初始化,可以透過提前初始化WebView最佳化此問題;二是資源(html、js、css\圖片等)的請求連線和載入,可以用H5離線包方案解決此問題,透過資源的預載入,解決html、js、css和資源圖片的載入問題,從而大大降低資源的載入時間,提升頁面載入效能,甚至達到秒開的效果。


05總結

那麼如何技術選型呢?應該以提升開發效率和使用者體驗為前提去思考,然後再分析關鍵因素:

1、技術棧的基礎架構如何,原始架構是否優秀,是否更面向未來發展;

2、團隊技術棧成熟度,學習的成本,社群的成熟度;

3、研發效率,實現程式碼多端複用,減少多端差異,降低開發成本,更加專注於業務開發;而效率提升是一個持續的收益過程,體現在業務發展的整個生命週期。當然,對於新技術在實踐前期會有一些成本,但熟悉後總的收益是長期的;

4、是否更好解決多端一致性,更好解決UI設計師在UI審查時、測試同學在測試過程中、業務方在使用過程中發現的端與端並異問題,風格統一也是良好使用者體驗的重要體現;

5、支援動態化的程度,解決新需求必須發版的問題,也是業務的痛點,關鍵因素;

6、使用者體驗是最關鍵的,也需考慮使用者的使用環境(網路環境、手機配置)等;

對於正式的C端專案,面對千萬甚至億級的使用者量,技術選型策略一定是在保證使用者體驗的基礎上實現降本提效,使用者第一,使用者利益最大化即保證了公司的利益;對於非C端專案,可能需要考慮在實現降本提效基礎上提升使用者體驗。


本文作者:京東國際技術研發部——盧旭、張公、姚峰、高鑫鵬、李澄鋒、陳海蛟、高明、凡為連、單禹欽、慕新建


相關文章