導讀
本文主要針對常用跨端技術Flutter、ReactNative、Weex、H5,從技術特點、基本架構(gòu)、編譯原理、基本渲染流程等進行梳理分析;以及一些常見性能問題如何優(yōu)化解決,然后如何進行技術選型或在進行業(yè)務開發(fā)時選擇不同技術棧的邏輯是什么。
01背景
在今年的敏捷團隊建設中,我通過Suite執(zhí)行器實現(xiàn)了一鍵自動化單元測試。Juint除了Suite執(zhí)行器還有哪些執(zhí)行器呢?由此我的Runner探索之旅開始了!
隨著技術的發(fā)展,產(chǎn)生了越來越多的端,如Android、iOS、Mac、Windows、Web、Fuchsia OS、鴻蒙等,而隨著公司業(yè)務的發(fā)展,出現(xiàn)了越來越多的業(yè)務場景;作為APP開發(fā)人員,在日常工作中難免會碰到以下問題,如:1、UI設計師在進行UI審查時、測試同學在回歸測試過程中、業(yè)務方在使用過程中,多少會發(fā)現(xiàn)端與端存在著差異,影響用戶體驗;2、同樣的業(yè)務、同樣的功能在不同的端上,需要每端投入資源去開發(fā)實現(xiàn)。而移動互聯(lián)網(wǎng)的發(fā)展已經(jīng)處于晚期,領導們越來越關心投入產(chǎn)出。
與此同時,出現(xiàn)了一些跨端的技術解決方案,可以實現(xiàn)一套代碼在多端運行,解決業(yè)務發(fā)展上的痛點,如Flutter、ReactNative、Weex、H5(注:小程序和其它基于DSL的方案暫不在本文討論范圍)。然后對一些常用APP進行了對比分析,結(jié)論和預期一致,大部分都在使用跨端技術;Flutter和ReactNative使用率較高,Weex使用率相對低一些,H5基本都在使用,使用多種跨端技術框架是一種常態(tài)。那么,它們都有哪些特點呢?
02 四種技術棧特點介紹
理解,首先 MCube 會依據(jù)模板緩存狀態(tài)判斷是否需要網(wǎng)絡獲取最新模板,當獲取到模板后進行模板加載,加載階段會將產(chǎn)物轉(zhuǎn)換為視圖樹的結(jié)構(gòu),轉(zhuǎn)換完成后將通過表達式引擎解析表達式并取得正確的值,通過事件解析引擎解析用戶自定義事件并完成事件的綁定,完成解析賦值以及事件綁定后進行視圖的渲染,最終將目標頁面展示到屏幕。
圖1-技術棧特點
通過圖1,從性能、開發(fā)語言、渲染、包大小、社區(qū)、支持平臺等方面梳理了它們的主要特點;不由產(chǎn)生幾個問題:為什么原生和Flutter性能更好?為什么ReactNative和Weex性能相對較差?為什么H5頁加載慢?這些性能問題該如何去優(yōu)化,這是需要深入了解的問題,下面將從基本的架構(gòu)、渲染流程、編譯運行原理等一起分析。
03基礎架構(gòu)介紹
3.1 Flutter基礎架構(gòu)介紹
ABM是Apple公司提供的iOS應用的分發(fā)渠道之一,與App Store平臺不同,ABM是2019年10月才開始在中國區(qū)啟動的一套全新的應用分發(fā)系統(tǒng),部分功能和企業(yè)賬號類似,旨在為企業(yè)提供快速、高效的方式來部署應用到企業(yè)擁有的蘋果設備。ABM與App Store兩個平臺的關鍵區(qū)別如下:
圖2-Flutter基礎架構(gòu)
Google在2018年發(fā)布了Flutter 1.0,如圖2所示,主要分為Framework層和Engine層;
Framework層:基于Dart實現(xiàn),主要包括Text、Image、Button、動畫、手勢等各種Widgets,核心基礎類庫io、async、ui等package;基于Framework開發(fā)App,其運行在Engine層上,F(xiàn)ramework和邏輯層都在基于Dart語言開發(fā),對于開發(fā)而言,一切都是Widget,Widget是UI實現(xiàn)的基礎;Engine層:基于C 、C實現(xiàn);主要包括Skia渲染引擎庫、Dart Runtime、Text文本渲染庫等,而Engine層自帶Skia渲染引擎,以此實現(xiàn)所有端的渲染展示統(tǒng)一,在Engine層適配平臺差異和跨平臺支持,實現(xiàn)更完美的跨端效果;Dart代碼通過AOT編譯為運行平臺的二進制代碼。也就是說Flutter不需要橋接,自己完成從邏輯側(cè)和渲染側(cè)的所有能力,和原生類似。這也是它性能突出的關鍵所在。另外Android自帶Skia引擎,所以也使得在Android的的編譯產(chǎn)物比iOS更小。除了支持移動端外,還支持Mac OS、Windows等PC端和Web端,在新的Funchsia OS也支持Dart,使用Flutter作為UI框架。
對于Flutter Web,F(xiàn)ramework層是公用的,意味著業(yè)務層可以使用此層的widgets實現(xiàn)邏輯跨端;但Engine層則不同,需要通過Canvas Render或者 HTML Render對齊Engine的能力。2022年5月Google IO大會發(fā)布Flutter 3.0,除了移動端,更好的支持了Mac OS、Linux平臺,也包括其它一系列優(yōu)化和支持,大家可以多關注。
3.2 ReactNative基礎架構(gòu)介紹
ABM是Apple公司提供的iOS應用的分發(fā)渠道之一,與App Store平臺不同,ABM是2019年10月才開始在中國區(qū)啟動的一套全新的應用分發(fā)系統(tǒng),部分功能和企業(yè)賬號類似,旨在為企業(yè)提供快速、高效的方式來部署應用到企業(yè)擁有的蘋果設備。ABM與App Store兩個平臺的關鍵區(qū)別如下:
圖3-ReactNative基礎架構(gòu)
ReactNative是Facebook于2015年開源,如圖3所示,主要服務于Android和iOS兩端,采用React開發(fā)實現(xiàn)邏輯側(cè)代碼(也可應用于前端),采用Redux實現(xiàn)狀態(tài)管理,在APP中UI渲染、網(wǎng)絡請求、動畫等均由原生側(cè)橋接實現(xiàn);在這里實際運行過程中,js側(cè)的dom會形成一個virtual dom,并通過bridge橋接將此dom結(jié)構(gòu)傳輸?shù)皆鷤?cè),原生側(cè)會解析并映射到原生控件,形成原生的dom結(jié)構(gòu)后,再調(diào)用原生能力進行渲染展示。
2021年ReactNative新版本對底層進行了重構(gòu),可以關注一下,如改變線程模型,引入異步渲染能力,允許多個渲染并簡化異步數(shù)據(jù)處理,簡化 JSBridge等。
3.3 Weex基礎架構(gòu)介紹
圖4-Weex基礎架構(gòu)
Weex是阿里2016年發(fā)布的跨端框架,如圖4所示,Weex編譯產(chǎn)物js bundle可以部署在服務端,APP加載完即可運行,也可以看出具備動態(tài)發(fā)布的能力;和ReactNative類似,Weex在實際運行過程中,js側(cè)會形成一個dom,并通過Bridge交由原生側(cè)解析,映射到原生控件再由原生能力進行渲染;Weex基于JS V8引擎,基于Vue設計,支持Android、iOS、Web三端。
3.4 WebView基礎架構(gòu)介紹
圖5-WebView內(nèi)核基礎架構(gòu)
WebView內(nèi)核模塊較復雜,如圖5所示,這里主要介紹WebView架構(gòu)主要的幾個部分:橋接協(xié)議是上層邏輯測與WebView的通信層,是JS和Native互相通信的能力層;
WebCore是瀏覽器加載和排版渲染頁面的基礎,主要包括資源加載、HTML解析、CSS解析、DOM解析、排版渲染等,JavaScript引擎是JavaScript解析器,JavaScriptCore是Webkit的JavaScript引擎,V8是Google的Blink的默認引擎;WebKit Ports是WebKit中移植部分,包括網(wǎng)絡、字體、圖片解碼、音視頻解碼、硬件加速等模塊;然后再往下也使用了很多第三方庫,包括2D圖形庫、3D圖形庫、網(wǎng)絡庫、存儲庫、音視頻庫等;最底層是操作系統(tǒng),支持Android、iOS、Windows等系統(tǒng)。
3.5 編譯原理分析
Flutter支持Release、Profile、Debug編譯模式。
Release模式即使用AOT預編譯模式,預編譯為機器碼,通過編譯生成對應架構(gòu)的代碼,在用戶設備上直接運行對應的機器碼,運行速度快,執(zhí)行性能好;此模式關閉了所有調(diào)試工具,只支持真機。對于編譯產(chǎn)物,iOS側(cè)主要生成App.framework和Flutter.framework;App.framework為dart代碼編譯產(chǎn)物,F(xiàn)lutter.framework為引擎編譯產(chǎn)物;Android側(cè)主要在lib下增加了libapp.so和libflutter.so,libapp.so為dart代碼編譯產(chǎn)物,libflutter.so為引擎編譯產(chǎn)物,不同的是在assets下增加了flutter_assets存放引用資源文件。
Profile模式和Release模式類似,此模式最重要的作用是可以用DevTools來檢測應用的性能,做性能調(diào)試分析。
Debug模式使用JIT即時編譯技術,支持常用的開發(fā)調(diào)試功能hot reload,在開發(fā)調(diào)試時使用,包括支持的調(diào)試信息、服務擴展、Observatory、DevTools等調(diào)試工具,支持模擬器和真機。iOS側(cè)主要生成App.framework和Flutter.framework,在App.framework文件夾里多了isolate_snapshot_data,kernel_blob.bin,vm_snapshot_data;Android側(cè)也同樣多了多了以上文件,但lib下少了libapp.so文件。
ReactNative整體分為邏輯側(cè)和渲染側(cè),邏輯側(cè)基于js引擎,會將基于React寫的代碼編譯為JavaScript原生代碼,再編譯生成jsbundle文件,內(nèi)置或下發(fā)到APP端運行;而渲染側(cè)依賴于Android或iOS原生渲染,需要分平臺編譯對應的編譯產(chǎn)物,然后發(fā)布到服務端或內(nèi)置到APP。
Weex和ReactNative類似,weex會將源碼編譯為js bundle,這些js bundle可以部署在服務端,APP下載完js bundle后,通過js引擎構(gòu)建虛擬dom并通過橋接映射到原生dom,由原生渲染引擎進行渲染。
H5:以React和Vue為例,會將以框架開發(fā)的代碼編譯為JavaScript原生代碼,即然后在瀏覽器或者WebView中執(zhí)行;內(nèi)核會先建立連接、加載資源,然后解析、排版布局、繪制渲染呈現(xiàn)給用戶。
3.6 基本渲染流程對比
圖6-基本渲染流程對比
簡單分析渲染流程,基于Android和iOS原生開發(fā)APP,調(diào)用Framework框架層實現(xiàn)上層邏輯,經(jīng)過布局繪制后直接調(diào)用系統(tǒng)渲染引擎進行渲染展示;基于Flutter開發(fā)APP,會直接調(diào)用Skia渲染引擎進行渲染展示;不依賴于原生渲染。
基于ReactNative或Weex開發(fā)APP則不同,首先業(yè)務邏輯是基于React或Weex開發(fā),然后會將js bundle包預置或下載到APP,然后將虛擬dom通過bridge映射到原生控件,再調(diào)用原生渲染引擎進行渲染展示。
基于Hybrid方案開發(fā)APP,需要通過React、Vue等前端框架實現(xiàn),首頁要編譯為JavaScript原生語言,然后通過鏈接在WebView或瀏覽器加載頁面,關鍵的流程是連接加載、解析、排版、繪制,最后再調(diào)渲染引擎進行展示。
通過以上所有分析,可以回答前面提出的問題:
為什么原生和Flutter性能更好?主是都是經(jīng)過布局繪制后直接調(diào)系統(tǒng)或自帶渲染引擎進行展示。
為什么ReactNative和Weex性能相對慢?主要是需要下載js bundle包,并把js dom結(jié)構(gòu)解析映射到原生,而下載和預置都比較耗時,并且依賴原生進行渲染(ReactNative新版本升級了基礎架構(gòu),據(jù)說有較大性能提升,大家也可以關注)。
為什么H5頁加載慢?主要因為連接和加載比較耗時,這里占大部分時間,連接和加載完以后基本就是WebView或瀏覽器本地可以完成的工作,后期優(yōu)化也可以以此為切入點。
04常見主要性能問題優(yōu)化
在實際開發(fā)過程中也遇到了一些性能問題,接下來進行簡單介紹。
4.1 如何優(yōu)化Flutter性能?
關鍵優(yōu)化指標:頁面異常率、頁面FPS幀率、頁面加載時長。
頁面異常率(異常發(fā)生次數(shù) / 整體頁面 PV 數(shù)):通過 runZoned 與 FlutterError 兩個方法,在異常攔截的方法中統(tǒng)計異常的發(fā)生次數(shù)和堆棧數(shù)據(jù)。
頁面FPS幀率:如何采集FPS是關鍵,通過window對象注冊onReportTimings回調(diào),就可以得到整個構(gòu)建和渲染過程的耗時,然后就可以算出頁面的FPS。
頁面加載時長(頁面可見的時間-頁面創(chuàng)建的時間):頁面可見的時間通過WidgetsBinding的addPostFrameCallback回調(diào)獲取,頁面創(chuàng)建的時間通過頁面初始化方法initState獲取。
將以上數(shù)據(jù)上傳到監(jiān)控和性能分析平臺(mPaaS和燭龍),作為后期性能分析和優(yōu)化的參考數(shù)據(jù),在開發(fā)過程中可通過DevToos性能分析工具、Flutter Inspector分析優(yōu)化性能。按需加載,局部刷新也是常用的優(yōu)化手段。其它性能優(yōu)化如布局加載優(yōu)化、狀態(tài)管理優(yōu)化、啟動優(yōu)化-引擎預加載、內(nèi)存優(yōu)化、包大小優(yōu)化等不再詳細介紹??梢远嚓P注Flutter社區(qū),定期升級Flutter版本,會帶來很好的收獲。
4.2 如何優(yōu)化ReactNative加載慢的問題?
一是可以預下載bundle包,減少包加載的時間,打開頁面直接映射渲染,從而達到更快打開頁面的目的,當然也可以預置包,需要平衡好包大小和性能;
二是嘗試升級ReactNative最新版本,新版本升級了基礎架構(gòu),主要包括線程模型,引入了異步渲染能力,優(yōu)化JSBridge,對性能有明顯提升(作者咨詢過京東mPaaS團隊,也在跟進中)。
4.3 如何優(yōu)化APP中H5加載慢的問題
圖7-加載H5流程介紹
圖7描述了從WebView初始化到H5頁面最終渲染的整個過程,以及和前面H5基本渲染流程進行分析。耗時環(huán)節(jié)的主要有兩點,一是WebView初始化,可以通過提前初始化WebView優(yōu)化此問題;二是資源(html、js、css圖片等)的請求連接和加載,可以用H5離線包方案解決此問題,通過資源的預加載,解決html、js、css和資源圖片的加載問題,從而大大降低資源的加載時間,提升頁面加載性能,甚至達到秒開的效果。
05總結(jié)
那么如何技術選型呢?應該以提升開發(fā)效率和用戶體驗為前提去思考,然后再分析關鍵因素:
1、技術棧的基礎架構(gòu)如何,原始架構(gòu)是否優(yōu)秀,是否更面向未來發(fā)展;
2、團隊技術棧成熟度,學習的成本,社區(qū)的成熟度;
3、研發(fā)效率,實現(xiàn)代碼多端復用,減少多端差異,降低開發(fā)成本,更加專注于業(yè)務開發(fā);而效率提升是一個持續(xù)的收益過程,體現(xiàn)在業(yè)務發(fā)展的整個生命周期。當然,對于新技術在實踐前期會有一些成本,但熟悉后總的收益是長期的;
4、是否更好解決多端一致性,更好解決UI設計師在UI審查時、測試同學在測試過程中、業(yè)務方在使用過程中發(fā)現(xiàn)的端與端并異問題,風格統(tǒng)一也是良好用戶體驗的重要體現(xiàn);
5、支持動態(tài)化的程度,解決新需求必須發(fā)版的問題,也是業(yè)務的痛點,關鍵因素;
6、用戶體驗是最關鍵的,也需考慮用戶的使用環(huán)境(網(wǎng)絡環(huán)境、手機配置)等;
對于正式的C端項目,面對千萬甚至億級的用戶量,技術選型策略一定是在保證用戶體驗的基礎上實現(xiàn)降本提效,用戶第一,用戶利益最大化即保證了公司的利益;對于非C端項目,可能需要考慮在實現(xiàn)降本提效基礎上提升用戶體驗。
版權聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 舉報,一經(jīng)查實,本站將立刻刪除。