天天看點

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

當下,移動動态化已經成為各大公司都回避不了的問題,産品的快速疊代對技術提出了更高的要求,而移動端的動态化方案也是層出不窮:Hypid、結構化

Native View、React

Native、Weex,什麼樣的方案才是适合自己團隊的呢?本文将分享餓了麼蜂鳥團隊在過去兩年多業務快速增長過程中,移動動态化方面的實踐和探索。

移動指的是移動端,包括安卓、iOS。動态化則是動态部署和邏輯下發到用戶端的能力。移動動态最好的狀态就是讓移動應用和 Web 一樣,想發就發!

為什麼移動端要強調動态化的能力?

原因有如下三大點:

    業務疊代太快。當下大部分團隊都是靈活開發的模式,即使兩周做一次疊代,産品周期還是會覺得長,有些應用不能及時上線。

    應用市場稽核慢。安卓基本當天發應用市場,當天就能夠有更新。但 iOS 需要約 3-4 天來稽核。假設有些功能需要定時上線,iOS 稽核時間必須要考慮進去。

    使用者更新周期長。統計表明,每一個安卓版本釋出,一周内會有 70% 的使用者更新,一個月其餘使用者才能陸續完成更新。

移動動态化方案共性,有如下三點:

    跨平台。

    布局。約定 DSL,保證渲染性能。

    邏輯。Android 和 iOS 必須共用解釋器。

蜂鳥團隊現狀

蜂鳥團隊于 2014 年成立,初衷是為了承接餓了麼的物流業務。随着時間推移,訂單量從每日幾千單到百萬單,配速員也達到百萬數量,服務品類涉及外賣、商超、鮮花、蛋糕、檔案等,蜂鳥提供全時段配送,配送服務覆寫全國 1200 多個城市。

蜂鳥團隊的業務特點

蜂鳥團隊的業務主要有離散性和突發性兩大特點,如下圖:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

從業務曲線可以看到兩個很明顯的波峰,這是午、晚用餐時間。同時,如果營運方面配置一些活動,會導緻這兩個波峰徒增。是以,動态方案要想把這兩個時間段服務好,必須要考慮流量陡增下的性能壓力。

蜂鳥團隊的技術特點和挑戰,我主要分享重度依賴、網絡環境複雜、重度使用和 28 定律這四個方面。

重度依賴

目前蜂鳥有衆包、團隊和送送三部分業務,右側是一些功能展示,如下圖:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

這樣的工具型應用,需要對 APP 有更強的控制、監控等能力。必要時還要做到強制更新。

對應到動态方案的話,控制能力就需要動态方案必須具備動态降級的能力、監控能力,實時的性能監控和業務埋點監控。強制更新方面,動态方案必須做到使用者無感覺的熱更新。

網絡環境複雜

餓了麼小哥,每天穿梭在大街小巷、地下商超,他們的網絡環境非常不穩定。據統計,有近 25% 的使用者請求還來自非 4G 環境。

整體來說的網絡環境複雜、信号差和 DNS 污染,那麼動态方案就要解決 DNS 攔截、弱網環境下資源下發等問題。

重度使用

無論是下雨、下雪,還是發洪水大家都會叫餓了麼。

配送員在高峰期的運動曲線,如下圖:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

面對這樣争分奪秒的準時達壓力,如果動态方案不給力,會導緻應用出現崩潰或卡頓,騎手必定不會有好的體驗,甚至影響送餐時間。是以我們的動态方案一定要保證性能和穩定性。

28定律

相信很多公司的應用都符合類似 28 定律,蜂鳥也不例外。

如下圖,蜂鳥的 28 定律:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

可以從圖中看出,大部分騎手日常使用的主流層面,可以采用 Native 來開發,這部分重度使用的占比約 20%,其餘 80% 的功能都可以考慮動态化方案(H5)。

蜂鳥的動态方案經過 Hypid、React Native 和 Weex 三個主要階段。

第一階段:Hypid

在 Hypid 方案上,以 H5 的動态性為基礎,通過 Jspidge 做橋梁,與 Native 進行通信,之後通過 URL Router 進行跳轉,架構如下圖:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

這套動态方案的優點顯而易見,這裡主要介紹開發效率、更新體驗和跨平台三方面:

    開發效率。Web 經過多年的應用實踐,已經擁有完整的開發流程和開發工具,開發一個 H5 頁面非常快速。開發效率這一因素不能忽略,因為初期産品的想法和落地速度會直接影響産品的命運。

    如蜂鳥送送,初期沒有原生的資源去支撐,就用原生包殼,内部全部用 H5,這樣的情況堅持了兩月左右,為蜂鳥送送前期的方案驗證做了很大的貢獻。

    更新體驗。因 H5 和原生耦合隻有擴充的 Native API,隻要把這些 API 維護足夠全,開發的業務功能就可以在完全不用更新 APK 的情況下,做到熱更新。且使用者下一次打開應用是最新的,這和 Native 的更新體驗相比簡直是一天一地。

跨平台。之前安卓和 iOS 代碼需要開發兩次,現在一個功能決定用 H5 後,由一個工程師來開發一套代碼即可。

這套動态方案很大的缺點就是使用者體驗差,當用 H5 做一些複雜的功能或動畫時,可能會卡頓的和 PPT 一樣。因為 H5 的體驗問題,蜂鳥的原則是經常更新的且功能不複雜的頁面會選擇用 H5。

第二階段:React Native

這個動态方案完全脫離了以 H5 為基礎的 Hypid 方案,通過自定義 DSL 将 UI 渲染成原生控件,這樣一來, RN 的頁面就保證了原生的體驗和 Web 的效率。

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

除了上一點,還有元件化開發、複用率高、Android 和 iOS 95% 的代碼共用和測試效率高等優點。

鑒于這些優點,蜂鳥在 React Native 上做了很多事情,如 Crash 優化、基礎控件沉澱、Bundle+ 圖檔熱更新、首屏加載優化和 Redux 單項資料流等。

正當享受 React Native 帶來的開發體驗和應用體驗提升時,蜂鳥遇到 RN 的一些痛點,如 ScrollView 性能、Bundle 包過大、很多優化都需要修改源碼和 peaking change 等。

第三階段:WEEX

面對如上這些痛點,不知如何應對時,WEEX 來了。官方宣傳的輕量、可擴充和高性能等特點,讓蜂鳥團隊眼前一亮。

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

經深入研究後,蜂鳥發現 WEEX 和 React Native 如出一轍,那麼為什麼要選擇類似的方案呢?

我們隊 WEEX 和 React Native 兩者基于 JS 引擎、文法、資料流、性能、開發體驗及熱更新等次元進行了對比。

如下圖,是 WEEX 和 React Native JS 引擎對比:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

React Native 在安卓和 iOS 使用的都是 JsCore,WEEX 在安卓端使用的是 UC 精簡版 V8。如上圖中的圖表可以看出,V8 相比 JsCore 要勝一籌。

WEEX 和 React Native 文法對比。文法方面,React Native 使用的是 React,WEEX 使用的是 Vue。雖然兩套方案都實作了如響應式,元件化、狀态管理等功能。

如下圖,是兩者簡單 Demo 的實踐:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

實踐發現,WEEX 相比 React Native 要優雅一些,是因為 Vue 有很多自定義标簽,當在做一些 UI 和邏輯交雜在一起時,會讓代碼簡潔很多。

 WEEX 和 React Native 的資料流對比,React Native 使用 Redux,而 WEEX 使用 Vuex,不是 WEEX 不能使用 Redux,而是 Vuex 更适合 WEEX。

如下圖,是兩者的資料流,大同小異:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

但 Vuex 在實作一些計算屬性時,能在更細的顆粒度去更新 UI,而 Redux 隻能實作到元件的級别,這樣的點很多的話會帶來性能上的差異。

如下圖,是 WEEX 和 React Native 的性能對比,左側是 WEEX 官方給出的與 React Native 在性能方面的對比圖:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

在渲染時間和記憶體占用方面 WEEX 要優于 React Native,在 CPU 占用方面兩者相差不大,FPS 上 WEEX 要稍遜于 React Native。

在 ListView Android 方面,React Native 目前采用 ScrollView,WEEX 使用 Recyclerview 實作,性能稍好。

同時 WEEX 在增強開發、指定線程、首屏渲染和性能監控等方面也做了優化。

如下圖,是 WEEX 和 React Native 的開發體驗對比:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

和 React Native 相比,WEEX 在打包、監控性能、跨平台等方面都有一定優勢。總體來說,React Native 更像是一個技術架構,WEEX 更像是一個業務架構。

如下圖,是 WEEX 和 React Native 的熱更新對比:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

React Native 與 WEEX 官方都表示支援熱更新,但他們的實作方式不同。在 React Native 上可通過把圖檔打包下發到本地來實作更新。

WEEX 有兩個方法,一是選擇本地資源加載,二是像網頁一樣直接加載頁面。

如下圖,是 React Native 與 WEEX 的對比總結:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

React Native 更像一個先驅者,擁有超強的社群人氣,但也因開源社群維護代碼的原因處于一個野蠻生長的狀态。而 WEEX 是站在 React Native 的肩膀上,做了各種微創新,實作更多貼心的小細節。

基于 WEEX 性能、穩定性等方面都比 React Native 高,蜂鳥決定把動态化方案往 WEEX 上遷移,雖然它現在還有不足,有些輪子還是要自己去做。

憑借之前 React Native 相關的實踐經驗,基于 WEEX 做了一套更完整的動态方案。涉及以下幾個方面,如下圖:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

統一的pidge 

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

在 Android & iOS 端,約定相同的方法名、參數,在 JS 層抹平平台差異以及統一分類管理暴露給業務的 API。

把這樣的統一 pidge 方案提供給業務部門,他們隻需關心暴露的 API,而不需要關心下一層平台的相容,大大提升開發效率。

加載更新政策

加載更新方面,我們約定了一套自有協定,有 Page、URL 和 Tag,通過封裝的 Router,就可以做到頁面級的跳轉。

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

這樣一來,我們很輕松地做到了頁面的跳轉、解耦和頁面的降級。當頁面出現問題,隻需要把 URL 改成降級之後的 H5 頁面下發即可,使用者觸及到的就是修複之後的 H5 頁面了。

如下圖,是預加載政策:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

當 H5 頁面下發到用戶端之後,會對本地資源進行檢查,如果有 JS 檔案,就忽略,沒有的話就把頁面下載下傳。當使用者打開頁面,再去看本地,存在資源的話直接加載,不存在的話就即時下載下傳再運作,與傳統的 Web 流程相似。

性能監控

性能監控用來判斷線上服務是否正常,是整套方案最重要的部分。

WEEX 可以很友善地将所有的參數全部拿到且通過反射拿到所有的性能資料傳到雲端。

基于這些資料,我們就可以知道線上有了哪些頁面,它的渲染是否有問題。基于這些問題,就可做相應的優化。

如下圖,是線上的資料情況:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

監控三個名額,分别是 JS 引擎的初始化時間、頁面打開時間和網絡時間。因大部分 WEEX 頁面都是業務,是以說業務埋點必不可少。餓了麼也實作了一套架構,将業務埋點傳給服務端,然後友善産品去制定一些産品方面的政策。

JS 的錯誤統計

可以捕捉 JS 端抛出的錯誤,如果所處團隊是前端主導,可傳給前端。如果是 Native 主導,可通過搜集平台将這些崩潰上傳,在背景看到這些錯誤之後,找到相應的代碼去修複。

Native 的錯誤

有了 JS 錯誤,Native 錯誤也不能忽略。

如下圖,是 WEEX 動态方案上線一周之後線上抛的錯誤:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

從圖中可以看到都是個位數,這一點其實當時也很驚訝,WEEX 确實做得很穩定,這一點超出預料。

共用元件和 API

之前蜂鳥在 React Native 上面的一些實踐,積累了一些很常用的元件和 API。WEEX 和 React Native 都是使用 JS 實作,是以我們很友善的将 RN 的控件轉化為 WEEX 控件。

如下圖,是實作的元件和 API,幾乎可以滿足中小團隊的日常使用:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

調試工具

這方面 WEEX 做的很貼心,雖然沒有整合到整個初始化的項目中,但開源了幾個庫,可把代碼拷貝到業務中進行使用。

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

WEEX 還可支援 Debug 模式顯示調試工具、支援 hot reload、友善的檢視性能名額和 Shell 腳本一鍵打包等功能。

綜上所述,基于這些次元實作的架構,可以友善的讓業務來使用。

如下,是餓了麼和蜂鳥用 WEEX 實作的兩個頁面:

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

餓了麼的第二個發現頁面,就是基于 WEEX。蜂鳥 APP 可能大家接觸不到,上圖是目前通知的活動界面,還有大量的新功能正在接入。

如果你正在考慮 WEEX 與 React Native 方案,或是正在接入 React Native。看到這篇文章,你可以去調研以下 WEEX 方案,可能你會有另一種選擇。

以上内容根據許錦洋老師在 WOTA2017 “移動端架構演進”專場的演講内容整理。

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

負責餓了麼蜂鳥 APP 的架構、研發等工作。擁有餓了麼商家、風行者、蜂鳥衆包等多款 APP 開發工作經曆,并從 0 開始架構和開發了整個蜂鳥團隊 APP。目前關注的技術方向為移動跨平台技術方案、移動端架構、移動端性能優化等。

移動動态化方案在蜂鳥的架構演進(含React Native與Weex對比)

繼續閱讀