React Native性能之謎

在PhoneGap坪仇、RubyMotion、Xamarin森渐、Ionic一眾跨平臺(tái)開發(fā)工具中,React Native能夠殺出一條血路谴垫,獲得目前這么大的影響力章母,除了React社區(qū)生態(tài)圈的加持和Facebook的大力推廣以外,另外一個(gè)最主要的原因就是其在開發(fā)效率和應(yīng)用性能方面取得了一個(gè)比較好的平衡:

  • 開發(fā)效率通過JS工程實(shí)踐翩剪,邏輯跨平臺(tái)復(fù)用得到極大提升
  • 性能則通過全Native的UI層得到滿足

不過,雖說框架提供了這個(gè)平衡能力彩郊,平衡點(diǎn)的選擇卻掌握在開發(fā)者手中前弯,本文將從React Native的性能角度來看看應(yīng)該如何掌握這個(gè)平衡點(diǎn)。

React Native的工作原理

在React Native的應(yīng)用中秫逝,存在著兩個(gè)不同的技術(shù)王國(guó):JS王國(guó)和Native王國(guó)恕出。應(yīng)用在啟動(dòng)時(shí)會(huì)先進(jìn)行雙向注冊(cè),搭好橋违帆,讓兩個(gè)王國(guó)知道彼此的存在浙巫,以及定義好彼此合作的方式:

(圖片來源:https://tadeuzagallo.com/blog/react-native-bridge/

然后,在應(yīng)用的實(shí)際運(yùn)行過程中刷后,兩個(gè)技術(shù)王國(guó)通過搭好的橋的畴,彼此合作完成用戶功能:

(圖片來源:http://www.reibang.com/p/978c4bd3a759)

因此,React Native的本質(zhì)是在兩個(gè)技術(shù)王國(guó)之間搭建雙向橋梁尝胆,讓他們可以相互調(diào)用和響應(yīng)丧裁。那么就可以把上圖簡(jiǎn)化一下:

React Native的性能瓶頸

經(jīng)過上面的分析,我們就可以把一個(gè)React Native應(yīng)用分成三個(gè)部分:Native王國(guó)含衔、Bridge煎娇、JS王國(guó)。當(dāng)應(yīng)用運(yùn)行時(shí)贪染,Native王國(guó)和JS王國(guó)各自運(yùn)行在自己獨(dú)立的線程中:

Native王國(guó):

  • 運(yùn)行在主線程上(可能會(huì)有些獨(dú)立的后臺(tái)線程處理運(yùn)算缓呛,當(dāng)前討論中可忽略)
  • iOS平臺(tái)上運(yùn)行Object-C/Swift代碼,Android平臺(tái)上運(yùn)行Java/Kotlin代碼
  • 負(fù)責(zé)處理UI的渲染杭隙,事件響應(yīng)哟绊。

JS王國(guó):

  • 運(yùn)行在JS引擎的JS線程上
  • 運(yùn)行JS代碼
  • 負(fù)責(zé)處理業(yè)務(wù)邏輯,還包括了應(yīng)該顯示哪個(gè)界面寺渗,以及如何給頁(yè)面加樣式匿情。

在Native王國(guó)中兰迫,經(jīng)過谷歌、蘋果公司多年的優(yōu)化調(diào)整炬称,Native代碼能夠非持快速的運(yùn)行在設(shè)備上。在JS王國(guó)中玲躯,JS代碼作為腳本語(yǔ)言据德,也能夠很快速的運(yùn)行在JS引擎上,這兩邊獨(dú)立來看都不會(huì)有性能問題跷车。性能的瓶頸只會(huì)出現(xiàn)在從一個(gè)王國(guó)轉(zhuǎn)入另一個(gè)王國(guó)時(shí)棘利,尤其是頻繁的在兩個(gè)王國(guó)之間切換時(shí),兩個(gè)王國(guó)之間不能直接通信朽缴,只能通過Bridge做序列化和反序列化善玫,查找模塊,調(diào)用模塊等各種邏輯密强,最終反應(yīng)到應(yīng)用上茅郎,就是UI層用戶可感知的卡頓。 因此或渤,對(duì)React Native的性能控制就主要集中在如何盡量減少Bridge需要處理的邏輯上系冗。

那么,什么情況下會(huì)需要Bridge處理邏輯呢薪鹦?

  1. UI事件響應(yīng): 所有的UI事件都發(fā)生在Native側(cè)掌敬,會(huì)以事件的形式傳遞到JS側(cè)。這個(gè)過程非常簡(jiǎn)單池磁,也不會(huì)涉及大量的數(shù)據(jù)轉(zhuǎn)移奔害。在React Native應(yīng)用中,業(yè)務(wù)邏輯框仔,應(yīng)用狀態(tài)舀武,數(shù)據(jù)都在JS側(cè),所以UI事件只是一個(gè)觸發(fā)器离斩,不會(huì)有性能問題银舱。
  2. UI更新:前面已經(jīng)說過JS負(fù)責(zé)決定應(yīng)該展示哪個(gè)界面,以及如何樣式化界面跛梗,因此UI更新的發(fā)起方是JS側(cè)寻馏,更新時(shí)會(huì)向Native側(cè)同步大量的UI結(jié)構(gòu)和數(shù)據(jù),這類更新經(jīng)常出現(xiàn)性能問題核偿,尤其是在界面復(fù)雜诚欠、變動(dòng)數(shù)據(jù)大,或者做動(dòng)畫、變動(dòng)頻繁時(shí)轰绵。
  3. UI事件響應(yīng)和UI更新同時(shí)出現(xiàn):在UI更新時(shí)粉寞,結(jié)構(gòu)變化不大,則性能問題不大左腔;但是如果這時(shí)又有UI事件觸發(fā)JS側(cè)邏輯處理唧垦,而該邏輯處理又比較復(fù)雜,耗時(shí)較長(zhǎng)液样,導(dǎo)致JS側(cè)沒有時(shí)間片處理與Native側(cè)數(shù)據(jù)同步時(shí)振亮,也會(huì)發(fā)生性能問題。

React Native的性能優(yōu)化措施

前面已經(jīng)解釋了React Native的性能瓶頸會(huì)在什么地方鞭莽,React Native官方也知道這些坊秸,其在React Native中提供了一些性能優(yōu)化措施幫助開發(fā)者克服這些性能問題:

  1. 框架自帶的React基于Virtual Dom的Diff算法保證了UI變動(dòng)時(shí)傳遞的只是變化的UI部分,盡量減少需要同步的數(shù)據(jù)澎怒。
  2. 通過Direct Manipulation的方式直接在底層更新了Native組件的屬性褒搔,從而避免渲染組件結(jié)構(gòu)和同步太多視圖變化所帶來的大量開銷。這樣的確會(huì)帶來一定的性能提升喷面,同時(shí)也會(huì)使代碼邏輯難以理清站超,而且并沒有解決從JS側(cè)到Native側(cè)的數(shù)據(jù)同步開銷問題。因此這個(gè)方式官方都不再推薦乖酬,更推薦的做法是合理使用setState()和shouldComponentUpdate()方法解決這類問題。
  3. 在遇到動(dòng)畫性能問題時(shí)融求,可以使用Annimated類的庫(kù)咬像,一次性把如何變化的聲明發(fā)送到Native側(cè),Native側(cè)根據(jù)接收到的聲明自己負(fù)責(zé)接下來的UI更新生宛。不需要每幀的UI變化都同步一次數(shù)據(jù)县昂。
  4. Native和JS混編,把會(huì)大量變化的組件做成Native組件陷舅,這樣UI的變更數(shù)據(jù)直接在Native側(cè)自己處理了倒彰,無需通過Bridge,而不變的內(nèi)部組件因?yàn)闆]有數(shù)據(jù)更新需要同步莱睁,所以也不會(huì)使用到Bridge待讳。框架提供的NavigatorIOS相對(duì)于Navigator的性能提升就是這種做法仰剿。
  5. 遇到事件響應(yīng)和UI更新同時(shí)發(fā)生導(dǎo)致的性能問題時(shí)创淡,可以使用Interaction Manager把那些耗時(shí)較長(zhǎng)的工作安排到所有互動(dòng)或動(dòng)畫完成之后再進(jìn)行。

探求性能和效率平衡的套路

在了解了React Native的性能瓶頸和優(yōu)化措施之后南吮,就可以大概總結(jié)一個(gè)探尋React Native開發(fā)效率和性能平衡點(diǎn)的套路:

第一步: 全JS實(shí)現(xiàn)琳彩, 從一開始在技術(shù)選型上用React Native就是為了保證開發(fā)的效率,在沒有遇到性能問題之前,最大化效率是團(tuán)隊(duì)的一致追求露乏。

第二步: 從JS側(cè)進(jìn)行性能優(yōu)化

  • 對(duì)于那些明顯會(huì)涉及Bridge碧浊、需大量處理邏輯的場(chǎng)景,比方說動(dòng)畫瘟仿,復(fù)雜的手勢(shì)操作響應(yīng)等箱锐,嘗試使用經(jīng)過優(yōu)化過的庫(kù)(比方說:Animated),一次傳遞動(dòng)畫或者數(shù)據(jù)整個(gè)數(shù)據(jù)的描述給Native猾骡,Native側(cè)自己會(huì)按照聲明執(zhí)行下去瑞躺。
  • 使用InteractionManager把耗時(shí)操作遞延到UI響應(yīng)之后,處理那些存在因?yàn)楹臅r(shí)的JS操作導(dǎo)致的UI響應(yīng)性能問題兴想。

第三步:在真機(jī)上實(shí)測(cè)幢哨,檢查性能問題點(diǎn)。不要過早優(yōu)化嫂便,找到問題點(diǎn)再一一處理捞镰。

第四步:如果經(jīng)過JS端的優(yōu)化策略之后,在設(shè)備上還是有性能問題毙替,可以把有問題的部分以Native方式實(shí)現(xiàn)岸售,這也是為什么要推薦React Native團(tuán)隊(duì)中有10%左右的Native Developer。在這個(gè)步驟中厂画,需要注意問題的隔離方式凸丸,假設(shè)一個(gè)場(chǎng)景:在移動(dòng)一個(gè)Container時(shí),Container的UI同時(shí)發(fā)生變化袱院,但是Container內(nèi)部的內(nèi)容并沒有發(fā)生變化屎慢,這種情況下,只需要用Native實(shí)現(xiàn)Container忽洛,Container內(nèi)部的組件還是以JS實(shí)現(xiàn)腻惠。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市欲虚,隨后出現(xiàn)的幾起案子集灌,更是在濱河造成了極大的恐慌,老刑警劉巖复哆,帶你破解...
    沈念sama閱讀 212,029評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欣喧,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡寂恬,警方通過查閱死者的電腦和手機(jī)续誉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來初肉,“玉大人酷鸦,你說我怎么就攤上這事。” “怎么了臼隔?”我有些...
    開封第一講書人閱讀 157,570評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵嘹裂,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我摔握,道長(zhǎng)寄狼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,535評(píng)論 1 284
  • 正文 為了忘掉前任氨淌,我火速辦了婚禮泊愧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘盛正。我一直安慰自己删咱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,650評(píng)論 6 386
  • 文/花漫 我一把揭開白布豪筝。 她就那樣靜靜地躺著痰滋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪续崖。 梳的紋絲不亂的頭發(fā)上敲街,一...
    開封第一講書人閱讀 49,850評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音严望,去河邊找鬼多艇。 笑死,一個(gè)胖子當(dāng)著我的面吹牛像吻,可吹牛的內(nèi)容都是我干的墩蔓。 我是一名探鬼主播,決...
    沈念sama閱讀 39,006評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼萧豆,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了昏名?” 一聲冷哼從身側(cè)響起涮雷,我...
    開封第一講書人閱讀 37,747評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎轻局,沒想到半個(gè)月后洪鸭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,207評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仑扑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,536評(píng)論 2 327
  • 正文 我和宋清朗相戀三年览爵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镇饮。...
    茶點(diǎn)故事閱讀 38,683評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蜓竹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情俱济,我是刑警寧澤嘶是,帶...
    沈念sama閱讀 34,342評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站蛛碌,受9級(jí)特大地震影響聂喇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蔚携,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,964評(píng)論 3 315
  • 文/蒙蒙 一希太、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧酝蜒,春花似錦誊辉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至远豺,卻和暖如春奈偏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背躯护。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工惊来, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人棺滞。 一個(gè)月前我還...
    沈念sama閱讀 46,401評(píng)論 2 360
  • 正文 我出身青樓裁蚁,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親继准。 傳聞我的和親對(duì)象是個(gè)殘疾皇子枉证,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,566評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容