【騰訊Bugly乾貨分享】React Native項目實戰總結

本文來自於騰訊bugly開發者社區,非經做者贊成,請勿轉載,原文地址:http://dev.qq.com/topic/577e16a7640ad7b4682c64a7html

「8小時內拼工做,8小時外拼成長」這是你們共同的理想。除了天天忙於工做外,咱們都但願能更多地區吸取領域內的新知識與新技能,從而走向人生巔峯。前端

Dev Club 是一個交流移動開發技術,結交朋友,擴展人脈的社羣,成員都是通過審覈的移動開發工程師。每週都會舉行嘉賓分享,話題討論等活動。vue

上一期咱們邀請了騰訊SNG工程師「王少鳴」分享了《React Native項目實戰總結》java

2016-07-14,下週四,咱們將邀請騰訊WXG iOS開發工程師「姚海波」爲你們分享《微信讀書iOS性能優化》

如何加入 Dev Club?android

移動端開發經驗 >= 2 年,微信掃描下方羣管理微信二維碼,備註姓名-公司(或產品) 申請加入。ios

—————-下面是上一期分享內容整理—————-git

內容簡介:web

你是否想體驗Web同樣的發佈節奏來發布終端的特性?npm

你是否想低成本讓先前的H5特性擁有Native同樣的流暢體驗?json

快來一塊兒擁抱ReactNative吧!

分享人介紹:

王少鳴,社交平臺部工程師。對前端系統的設計和開發有豐富的經驗,前後從事PC Qzone前端開發,小Q機器人智能終端開發及微信羣,手機Qzone終端開發等工做。

1

Hello,你們晚上好,我是來自QQ空間的王少鳴,你們能夠叫我mango,目前主要負責 Qzone 玩吧業務,專一Hybrid開發,[QQJsSDK] 研發負責人,專一ReactNative在Qzone與手Q的應用和推廣。照片裏的這我的就是我,上週在GMTC分享拍的,請你們多多指教。

接下來進入正題,請你們先認識下這幾個簡寫:

fb = Facebook
 rn = ReactNative
 jsc = Javascript Core
 cxt = Context

ReactNative 讓開發者使用 JavaScript 和 React 編寫應用,利用相同的核心代碼就能夠建立 基於Web,iOS 和 Android 平臺的原生應用。Facebook 在2015.9.15發佈了 ReactNative for Android,把JavaScript 開發技術擴展到了Android平臺,至此已覆蓋當流主流平臺。

2

目前ReactNative的版本節奏大概是兩週一個版本,空間從11的版本便開始嘗試接入,第一個上線的版本是15的版本,後面咱們升級到20的版本,因爲一些歷史包袱的緣由,致使咱們升級並不能隨時跟隨fb的升級節奏。手Q方面目前使用的是17的版本。

3

咱們從fb rn的官網中的showcase頁面能夠看到,目前已經有大量的app接使用了rn的技術,當前,還能看到咱們公司的很多app,如QQ,Qzone,QQ音樂,全民k歌等,這個你們若是有興趣想要把本身的app放到官網上,只須要要向fb提交一個pr便可。

4

目前在空間有三個業務使了用rn進行開發,有話題圈,情侶空間,結合版留言版等。在手Q方面,有消息流和資料卡等,固然,還有全民k歌的一些活動頁。

接下來咱們來對比下rn與原生開發或hybrid開發有些哪優劣勢。

優點:

  • 原生控件的體驗,Web的版本節奏,Web的開發效率,跨平臺等

    劣勢:

  • 版本支持度 Android 4.1 (API 16) & iOS 7.0

  • 項目尚不成熟,容易Crash,部分機器存在兼容性問題
  • 性能,在高低端機呈現兩極
  • Android僅基於Gradle,目前業界較多大平臺項目均基於 Ant,如Qzone,手Q等

特別是最後一點,這個也是咱們前面說的,版本升級不能跟隨fb rn版本的緣由,咱們的每次升級都須要將rn源碼進行改造和合並,接口適配等,對開發有必定的額外的工做量。

接下來,咱們來看下,使用rn開發的版本總體流程。

5

首先,咱們的app集成了rn的sdk,另外,jsbundle也就是咱們使用rn開發的上層業務邏輯代碼。咱們在發佈app時,咱們會內置一份。當上層業務邏輯變化時,咱們會從新向咱們的cdn發佈一份新的jsbundle。在app啓動時,咱們檢查當時外網有沒有jsbundle須要更新,若是有,咱們們更新並存放本地。在點擊應用入口時,咱們會優先使用新下載的這份文件,不然使用內置的,最後經過JSC進行渲染,獲得咱們最終的頁面。

ok,瞭解了版本的總體流程,再簡單來看看rn原理。

6

前面咱們講到了jsc,那jsc就是橋接web<>native的一個組件,在必定意義上等同於咱們的瀏覽器內核。那講完jsc,那原理就比較容易理解了,就是經過jsc去解析咱們的jsbundle,並將信息傳遞給native,最後由native不斷去處理來自js層的調用,最終獲得咱們的native頁面。

網上分析rn在iOS的文章也比較多了,我這邊也很少講,主要講下在android方面的。

7

主要分爲三層:

  1. java層:主要有ReactCore,主要處理與js的交互,還有處理圖片的fresco,網絡庫okhttp,還有一些support和utils等。
  1. C++層:主要有咱們的jsc,bridge,,jsloader等
  1. JS層:這層相對你們就比較熟悉了,主要是包含組件的邏輯處理和一些佈局,固然,這些佈局信息最終也是轉成咱們終端的佈局模型。

接下來,咱們來看一下js跟native的通訊機制。

這塊內容實際上是rn裏很重要的內容,這塊主要是流程比較長,咱們今天就簡單講一下,詳細的有興趣的同窗,能夠去公衆號看我以前寫文章,或者直接找我。

先來看看從java層到js層的調用。

8

咱們的業務邏輯實際上是在js裏面,那就這裏出現了咱們的啓動邏輯,這裏其實就是java層到js層調用的一個例子,由java去調用js的某個啓動函數。

那js層到java層的調用就更多了,好比像點擊圖片點看大圖浮層,這裏更可能是業務性質的調用。

9

固然,還有另一個可能你們比較關注的問題,就是前端寫的標籤,好比咱們的 這樣一個組件,是怎麼轉換到終端的一個view?這裏其實原理也很簡單,js層會將控件標籤轉換成js對終端UI模塊的一次調用,如比像這種UIManager.creaeView或者UIManager.removeView咱們不管是java到js仍是js到java,中間都必須通過咱們的jsc進行橋接。

上一張稍微複雜點的調用鏈

10

這個講起來時間稍微有點長,其實就是說明標籤到控件的一個完整調用鏈,有興趣的同窗咱們下來再討論。

好了,前面原理講得比較多,由於可能有先同窗先前沒接觸過rn,我這裏就先講些基礎知識。接下來咱們講些可能你們比較感興趣的,就是咱們踩坑和填坑之路。

那在接下rn以前,咱們會遇到了下面幾個問題:

  1. 包大小:Android HelloWorld工程 約7m
  2. 穩定性:業界還沒有有真實外網數據,內部僅能經過大量機器進行穩定性測試,但未能覆蓋全部機型
  3. 安全性:Jsbundle可能發生被攔截等狀況,容易致使Native Crash
  4. 兼容性:Android 4.1 (API 16) & iOS 7.0 Jsbundle與Native版本兼容 支持版本對機型兼容
  5. 性能:業界還沒有有真實外網數據,僅靠實驗室有限數據支撐

基於上面這幾個問題,咱們決定第一個版本,使用rn來改造以前的情侶空間業務(H5),咱們使用獨立插件的技術來實現。

獨立插件經過異步下載,而且,咱們使用獨立進程來承載它防止拖垮主進程,最後,再加個雲開關,假如外網有問題能夠隨時將rn切到h5。
這裏第一個項目的細節就不細講了,在這個項目,主要是想經過這個第一涉水項目,咱們發現了哪些問題,以及咱們是怎麼解決的。主要是首屏方面,咱們經過實驗log數據,得知wifi下,首屏將近6s才能徹底渲染出來。其次,fps主觀上沒明顯卡頓,中低端機對比老版本降低明顯,這個兩個問題。

11

接下來,咱們決定進行第二個業務話題圈使用rn進行改造。背景是話題圈先前是h5的,裏面的視頻組件沒法支持本身播放及續播相關邏輯,那組件開發相開發時間關係這裏就不細講,有興趣你們能夠下來討論。

12

那咱們將先前情侶空間的log進行分塊,主要是 插件及進程啓動 2.1s+RN上下文啓動+1.1s 首屏數據+2s Render 0.9s。接下來咱們分塊解決這些問題。

插件及進程啓動:消滅這份耗時其實比較容易,rn和Qzone集成並綁在主進程便可。可是集成咱們遇到一個問題就是Qzone是基本ant的構建,rn是基於gradle的構建,二者沒法直接融合,那隻能是將rn改造ant的構建。(qzone改造gradle代價比較大,週期長)關於更改構建這裏,你們能夠去看我km的一篇文章便可,時間有限,便不細講了。

那咱們話題圈最終改造的計劃是:

ant改造rn -> 集成到Qzone -> 業務開發 -> 性能優化

時間問題,咱們着重看性能優化方面的知識,可能有些我也講得不深,也有些針對性,但願能給你們帶一些新啓發更關鍵。

集成到Qzone主要是方法數的問題,那業務開發,我簡單講一個點,就是在開發前,終端同窗須要與前端同窗定製好大家業務的全部接口。這裏我有個建議,形參建議只保留兩個,一個是大家業務數據的json,另一個就是cb。由於rn在接口調用方法,若是參數個數對不上,會直接致使應用crash。

那咱們接下來看性能優化方面的東西,咱們這裏已經將Qzone與rn進行集成了,那關於插件啓動和進程啓動的耗時已經能夠消除,那接下來咱們看下,怎麼去消除首屏和上下文的耗時。

那咱們先來看一下,一個傳統的啓動流程:

點擊入口 -> native cxt -> web cxt -> 前端發起數據請求 -> 回包 -> 渲染

很明顯,這裏的流程是串行的,那咱們是否是把一些東西並行起來,或者提早先作呢?
和其餘啓動優化相似,仍是內存換時間,咱們這裏加了預加載的邏輯。

預加載啥呢?咱們這裏預加載的是native cxt。假如大家的業務在二級頁的話,我以爲預加載是沒啥問題的,固然在主頁面或者整個app都是用rn的話,可能就得換種思路了。
另外數據的話咱們是這樣作的。首先,咱們給前端提供一個數據模塊,這個模塊提供能夠讀寫本地數據的接口。咱們點擊入口的時候,終端會先去拉後臺數據並存到sdcard,那當咱們點擊入口,前端再使用的咱們提供的數據模塊,讀取緩存的數據進行渲染。當時,咱們前端仍是照樣會發請求給後臺拉最新的數據,隨後覆蓋到sdcard,假如數據有更新話,前臺頁面再從新渲染。最終咱們的首屏定格在1.5s左右。(因爲話題圈頁面相對比較重,咱們以前使用的是wns-html技術,這個數據其實已經超越了以前該頁面的首屏速度)

那首屏講完了,咱們來看下FPS,對比咱們以前的情侶空間,咱們此次FPS一樣有不少的提高,其實不少的優化思路咱們是從前端優化思想中借鑑過來,像FPS就是,咱們作了如下的優化:

UI方面:

  1. 減小View層級嵌套
  2. 合理設置背景色透明

JS方面:

  1. JS層使Listview控件渲染數據,廢棄使用ScrollView控件
  2. 避免滑動作過多事情,減小JS線程掉幀

最終FPS基本定格在53-54左右。

咱們最後再來看一下包精簡的方案。原始的rn接近7m左右,那裏面是否是有些優化空間呢?不少人在說,咱們平臺也有本身的網絡庫,真得還得使用rn裏面的okhttp麼?圖片庫也是,不能複用麼?實際上是能夠,咱們一塊兒來看下包精簡。那包精簡主要分爲下面4部分:

SO:

  1. 放棄對x86的支持
  2. 借用TBS能力,移除JSC

Java:

  1. 去除暫時不須要Module&UIManager
  2. Release 去除Dev Support

Jar:

  1. 對接平臺網絡庫(WNS,MSF),移除OKHTTP
  2. 對接平臺圖片庫(ImageManager),移除Fresco
  3. 平臺 Support 閹割庫 複用補齊

    Res:

  4. 移除無用的Res文件,language val

  5. 平臺 Support Res複用補齊


接下來,咱們來看下crash方面的一些小經驗。咱們從三方面來分析crash。

  1. 先來看看so層的crash,這層的crash會比較被動,由於基本沒辦法去解決,通常都只能等官方來更新解決,先前咱們碰到一個處理cookie的crash,其實咱們並無調用那個api,但系統本身啓動調用了,咱們當時的解決方案是將java的調用入口註釋了。固然,還有一些so兼容的crash等等。
  1. java層的crash相對還好,源碼在手,天下任走,這塊咱們能夠隨意修復,但建議是本身必定要把修改備註好,不然後面升級等都是災難。
  1. 最後來看看js層的crash,前面幾天我在gmtc分享的時候,就有個兄弟專門過來我問了我這個問題,他們遇到了js層一些屬性轉換的問題,而且直接表現就是實然crash。那這個問題,其實也困攏了我好久,我這邊也沒太好的解決方案,咱們和前端同窗定位過,屬性類型確定是沒問題的,最後咱們時間問題,解決方案是改動源碼。源碼在處理屬性等問題上,稍微一言不和就直接throws exception,那咱們這裏臨時的解決方案也只能是將throws改動log的標記,臨時解決而後靜等升級。

這裏再稍微講一下,咱們在手Q方面的一些實踐,固然這塊參與的同窗比較多了,這些也不僅僅由我一我的完成的。先來看一下咱們這邊又作了哪些優化。

主要有如下兩方面:

  1. 分包。前面咱們講預加載的知識。咱們當時預加載的僅是native cxt,那咱們可不能夠把前端cxt也加載了呢?其實確定是能夠 ,咱們試過直接預加載到整一個view的級別,可是,這樣會增長近40m的內存,固然是秒開,可是仍是要保證內存和首屏的權衡。後來,咱們進一步思考,假如後續業務衆多,每次業務切換是否每次都去從新加載那個1m多的jsbundle呢?後來,咱們有了另一個方案,就是將jsbundle進行拆分爲base和busi兩個zip。base咱們進行預加載,而且,咱們在業務切換的時候,咱們會進行復用,能更有效地提升首屏的速度。
  1. 獨立進程操做so。這個主要是由於手Q對內存要求比較嚴格,在界面退出的時候全部連帶內存必須清理乾淨。那rn在這方面其實作的並無那麼好,有部分so層的內存一直佔用着。那咱們解決方案只能是將JNI拆分爲獨立進程而且在界面退出時,直接退出dalvik,回收全部內存。固然,這裏就有些老技巧了,無非是進程預加載和延遲銷燬。

接下來,咱們看下總體在手Q這邊次優化後,咱們總體的數據對比


最後,咱們分享下幾個工具:

ReactNative Tools

  • adb logcat *:S ReactNative:V ReactNativeJS:V
  • Developer menu.

System Tools

  • 調試GPU過分繪製
  • GPU呈現模式

Android Tools

  • TraceView
  • Memory Monitor
  • TraceView
  • SysTrace

好了,今天分享就到這了,感謝你們耐心聽我叨叨了這麼多,謝謝你們,若是你們有疑問的話,能夠按序發在羣裏,能力範圍內的我按順序回覆你們,感謝!

問答環節

Q1:rn中用到js實現的邏輯容易出現性能問題嗎?

A1:性能瓶頸仍是在終端上,前端目前暫沒發現嚴重的性能問題。

Q2:目前的空間和QQ都是部分使用RN,後面會繼續擴大使用範圍嗎?

A2:確定會的。rn目前是快速成長期,咱們對rn有長期的歸劃。一樣,但願更多兄弟團隊一塊兒來推進rn的成長,一塊兒來貢獻一份力

Q3:以前聽到外界有團隊抱怨 RN 相對原生來講組件太少,反而加大了開發量,什麼都要本身來,如今是否有改善了呢?

A3:目前來看,其實組件是知足大部分開發者的,除非像某特些定製化的組件,好比像emojtext這種,咱們才須要本身去自定義,固然,如今git上面也不少rn的組件了,應該能知足你

Q4:剛纔分享的一些crash的例子好像都會致使rn直接崩掉,那大家用什麼手段來定位到底是那段js代碼致使問題呢?

A4:這裏還要講明一點。主是掌握源碼纔有真正的主動權。不少問題,咱們也都是去閱讀源碼發現的。其實源碼並不複雜,裏面不少知識沉澱,我我的是很是建議去讀源碼的。

Q5:我是作安卓的,不知道要不要嘗試一下這個新技術? 如今團隊作一些應用也不是很重,安卓和ios搞兩套實在有些蛋疼

A5:android iOS兩套這個問題,其實只是某些基礎組件屬於平臺特有,但大部分邏輯仍是有共性的。

Q6:目前rn發展還未穩定,預測一下將來是否會大規模應用並取代傳統的native開發,真正實現一次編寫,處處運行?

A6:動態更新其實這個問題很早前就有人提出,像插件啊,熱更新其實目的也是一致的,rn只是另一鍾思路,weex也相似。徹底取代native 開發我的以爲不太現實,由於像rn仍是須要native的一些開發工做的。

Q7:自定義ui組件須要對rn適配嗎?

A7:須要。但適配工做量並不高,僅對接相應接口,暴露一些屬性便可

Q8:RN整套框架是基於原生構建的,UI接口升級的時候整套框架可以及時保持兼容嗎?

A8:這裏還要說明一下,jsbundle的版本跟native的版本實際上是不兼容的。這裏建議jsbundle的url都使用後臺下發。另外,接口在升級後可能會有些改變,這裏須要前終端一塊兒配合

Q9:rn跨平臺的話是否是仍是須要維護兩套js,只是有些組件能夠跨平臺共用呢?

A9:其實維護的js代碼是一套。但可能在構建成特別平臺的jsbundle前有小小的修改。大部分組件仍是能夠複用的,除了平臺特有的,好比像actionbar這種

Q10:關於使用rn遇到的crash狀況,你以爲rqd能夠在哪些方面優化,幫助更好解決問題?

A10:目前業務使用rn的大平臺還比較少,其實不少crash咱們也在放量外網以後才發現的。這裏我比較建議是在使用rn前,先大體讀下rn的源碼,並正式發佈前多加一層保險開關。當前,目前就qzone使用的版本我也提交了一些pr,有些也收錄了,後面相信 crash等會愈來愈少的

Q11:從Android的機型問題看,最怕的就是平臺還不成熟,而且還開源。rn會不會重蹈覆轍?

A11:rn目前是開源的。目前開發者社區都是高活躍,應該不會存在kpi項目之類的問題,而且動態更新確定是趨勢,我以爲可能會有其餘方案,但暫時來看,rn仍是至關優秀的解決方案的

更多精彩內容歡迎關注bugly的微信公衆帳號:

騰訊 Bugly是一款專爲移動開發者打造的質量監控工具,幫助開發者快速,便捷的定位線上應用崩潰的狀況以及解決方案。智能合併功能幫助開發同窗把天天上報的數千條 Crash 根據根因合併分類,每日日報會列出影響用戶數最多的崩潰,精準定位功能幫助開發同窗定位到出問題的代碼行,實時上報能夠在發佈後快速的瞭解應用的質量狀況,適配最新的 iOS, Android 官方操做系統,鵝廠的工程師都在使用,快來加入咱們吧!

相關文章
相關標籤/搜索