本文來自於騰訊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終端開發等工做。
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平臺,至此已覆蓋當流主流平臺。
目前ReactNative的版本節奏大概是兩週一個版本,空間從11的版本便開始嘗試接入,第一個上線的版本是15的版本,後面咱們升級到20的版本,因爲一些歷史包袱的緣由,致使咱們升級並不能隨時跟隨fb的升級節奏。手Q方面目前使用的是17的版本。
咱們從fb rn的官網中的showcase頁面能夠看到,目前已經有大量的app接使用了rn的技術,當前,還能看到咱們公司的很多app,如QQ,Qzone,QQ音樂,全民k歌等,這個你們若是有興趣想要把本身的app放到官網上,只須要要向fb提交一個pr便可。
目前在空間有三個業務使了用rn進行開發,有話題圈,情侶空間,結合版留言版等。在手Q方面,有消息流和資料卡等,固然,還有全民k歌的一些活動頁。
接下來咱們來對比下rn與原生開發或hybrid開發有些哪優劣勢。
優點:
原生控件的體驗,Web的版本節奏,Web的開發效率,跨平臺等
劣勢:
版本支持度 Android 4.1 (API 16) & iOS 7.0
特別是最後一點,這個也是咱們前面說的,版本升級不能跟隨fb rn版本的緣由,咱們的每次升級都須要將rn源碼進行改造和合並,接口適配等,對開發有必定的額外的工做量。
接下來,咱們來看下,使用rn開發的版本總體流程。
首先,咱們的app集成了rn的sdk,另外,jsbundle也就是咱們使用rn開發的上層業務邏輯代碼。咱們在發佈app時,咱們會內置一份。當上層業務邏輯變化時,咱們會從新向咱們的cdn發佈一份新的jsbundle。在app啓動時,咱們檢查當時外網有沒有jsbundle須要更新,若是有,咱們們更新並存放本地。在點擊應用入口時,咱們會優先使用新下載的這份文件,不然使用內置的,最後經過JSC進行渲染,獲得咱們最終的頁面。
ok,瞭解了版本的總體流程,再簡單來看看rn原理。
前面咱們講到了jsc,那jsc就是橋接web<>native的一個組件,在必定意義上等同於咱們的瀏覽器內核。那講完jsc,那原理就比較容易理解了,就是經過jsc去解析咱們的jsbundle,並將信息傳遞給native,最後由native不斷去處理來自js層的調用,最終獲得咱們的native頁面。
網上分析rn在iOS的文章也比較多了,我這邊也很少講,主要講下在android方面的。
主要分爲三層:
接下來,咱們來看一下js跟native的通訊機制。
這塊內容實際上是rn裏很重要的內容,這塊主要是流程比較長,咱們今天就簡單講一下,詳細的有興趣的同窗,能夠去公衆號看我以前寫文章,或者直接找我。
先來看看從java層到js層的調用。
咱們的業務邏輯實際上是在js裏面,那就這裏出現了咱們的啓動邏輯,這裏其實就是java層到js層調用的一個例子,由java去調用js的某個啓動函數。
那js層到java層的調用就更多了,好比像點擊圖片點看大圖浮層,這裏更可能是業務性質的調用。
固然,還有另一個可能你們比較關注的問題,就是前端寫的標籤,好比咱們的 這樣一個組件,是怎麼轉換到終端的一個view?這裏其實原理也很簡單,js層會將控件標籤轉換成js對終端UI模塊的一次調用,如比像這種UIManager.creaeView或者UIManager.removeView咱們不管是java到js仍是js到java,中間都必須通過咱們的jsc進行橋接。
上一張稍微複雜點的調用鏈
這個講起來時間稍微有點長,其實就是說明標籤到控件的一個完整調用鏈,有興趣的同窗咱們下來再討論。
好了,前面原理講得比較多,由於可能有先同窗先前沒接觸過rn,我這裏就先講些基礎知識。接下來咱們講些可能你們比較感興趣的,就是咱們踩坑和填坑之路。
那在接下rn以前,咱們會遇到了下面幾個問題:
基於上面這幾個問題,咱們決定第一個版本,使用rn來改造以前的情侶空間業務(H5),咱們使用獨立插件的技術來實現。
獨立插件經過異步下載,而且,咱們使用獨立進程來承載它防止拖垮主進程,最後,再加個雲開關,假如外網有問題能夠隨時將rn切到h5。
這裏第一個項目的細節就不細講了,在這個項目,主要是想經過這個第一涉水項目,咱們發現了哪些問題,以及咱們是怎麼解決的。主要是首屏方面,咱們經過實驗log數據,得知wifi下,首屏將近6s才能徹底渲染出來。其次,fps主觀上沒明顯卡頓,中低端機對比老版本降低明顯,這個兩個問題。
接下來,咱們決定進行第二個業務話題圈使用rn進行改造。背景是話題圈先前是h5的,裏面的視頻組件沒法支持本身播放及續播相關邏輯,那組件開發相開發時間關係這裏就不細講,有興趣你們能夠下來討論。
那咱們將先前情侶空間的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方面:
JS方面:
最終FPS基本定格在53-54左右。
咱們最後再來看一下包精簡的方案。原始的rn接近7m左右,那裏面是否是有些優化空間呢?不少人在說,咱們平臺也有本身的網絡庫,真得還得使用rn裏面的okhttp麼?圖片庫也是,不能複用麼?實際上是能夠,咱們一塊兒來看下包精簡。那包精簡主要分爲下面4部分:
SO:
Java:
Jar:
平臺 Support 閹割庫 複用補齊
Res:
移除無用的Res文件,language val
平臺 Support Res複用補齊
接下來,咱們來看下crash方面的一些小經驗。咱們從三方面來分析crash。
最後來看看js層的crash,前面幾天我在gmtc分享的時候,就有個兄弟專門過來我問了我這個問題,他們遇到了js層一些屬性轉換的問題,而且直接表現就是實然crash。那這個問題,其實也困攏了我好久,我這邊也沒太好的解決方案,咱們和前端同窗定位過,屬性類型確定是沒問題的,最後咱們時間問題,解決方案是改動源碼。源碼在處理屬性等問題上,稍微一言不和就直接throws exception,那咱們這裏臨時的解決方案也只能是將throws改動log的標記,臨時解決而後靜等升級。
這裏再稍微講一下,咱們在手Q方面的一些實踐,固然這塊參與的同窗比較多了,這些也不僅僅由我一我的完成的。先來看一下咱們這邊又作了哪些優化。
主要有如下兩方面:
獨立進程操做so。這個主要是由於手Q對內存要求比較嚴格,在界面退出的時候全部連帶內存必須清理乾淨。那rn在這方面其實作的並無那麼好,有部分so層的內存一直佔用着。那咱們解決方案只能是將JNI拆分爲獨立進程而且在界面退出時,直接退出dalvik,回收全部內存。固然,這裏就有些老技巧了,無非是進程預加載和延遲銷燬。
接下來,咱們看下總體在手Q這邊次優化後,咱們總體的數據對比
最後,咱們分享下幾個工具:
ReactNative Tools
System Tools
Android Tools
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 官方操做系統,鵝廠的工程師都在使用,快來加入咱們吧!