原文出處: facebook 譯文出處:@Siva海浪高 react
該文章翻譯自Facebook官方博客,傳送門git
React Native 容許咱們運用 React 和 Relay 提供的聲明式的編程模型,寫JavaScript來構建咱們的 iOS 和 Android 的應用。這樣的作法使得咱們的代碼更精簡,更容易理解和閱讀,這些代碼還能夠在多個平臺共享。咱們也能夠加快迭代速度(由於在開發時不用等待漫長的編譯。使用React Native,咱們能夠發佈更快,打磨更多細節,讓應用運行的更流暢。這其中優化性能是咱們工做的一大重要部分,接下來說述 Facebook 如何使應用性能足足提高兩倍的故事~github
當應用運行的更快,內容加載的更迅速,就意味着用戶能夠有更多時間來使用應用,流暢的動畫讓用戶更加享受的使用應用。在新型市場中,2G網絡和幾年前的機型仍是主力。這時那些性能良好的和那些運行卡頓就有很大差異了。web
自從發佈了 iOS 和 Android 版本的 React Native 後,咱們團隊一直在諸如 提高列表視圖的滾動性能,優化內存佔有,讓 UI 界面更具響應性和加快應用啓動速度 上作了很多工做。這其中應用啓動關乎初次印象和是框架其餘部分的壓力源頭,因此它是要解決的頭等難題。編程
咱們把Facebook的iOS版中的事件主頁用RN從新實現(在更多標籤頁下點擊事件進入查看)。這是個很是好的用於測試性能的例子,由於原生版已經作了大量的優化工做,並且該頁面也是很是好的典型列表交互的例子。react-native
接下來,咱們自動化的 CT-Scan 性能測試來幫助咱們自動定位到咱們須要到的標籤頁。而後反覆打開和關閉事件主頁50次。在每次交互中,咱們可以記錄下從點擊事件按鈕到事件主頁可以被完整顯示的時間,咱們也添加更多詳細的性能埋點來告訴咱們啓動過程哪些步驟是緩慢或消耗CPU的緩存
下面是咱們記錄和測量的一些步驟的大體描述:性能優化
1 原生啓動:初始化JavaScript虛擬機和其餘一些原生模塊(如磁盤緩存,網絡,UI管理器等)服務器
2 JS初始化和依賴加載:從手機存儲中讀取被壓縮的JS代碼,加載到JavaScript虛擬機,從而解析和產生字節碼,加載相關的依賴網絡
3 取數據前:加載和執行事件主頁的應用代碼,構建Relay的查詢語句,而後觸發取數據。
4 取數據:從手機磁盤緩存讀取數據
5 JS渲染:初始化全部相關的React組件,把它們發送到原生的UI管理器模塊來顯示。
6 原生渲染:在shadow線程中先經過根據 FlexBox 佈局計算視圖大小。而後在主線程中建立和定位這些視圖。
咱們根據於此的黃金法則是:永遠不要忘了迴歸測試。咱們持續的運行它來追蹤性能提高和功能迴歸。開發者在提交改動的代碼以前用它對特定的提交作運行和詳細的性能分析。其餘的一些測試也須要被一樣的方式創建來衡量諸如功能性能和內存使用等
當咱們設置好自動性能追蹤,咱們須要一個工具來給咱們更多細節來決定啓動過程當中的那些部分須要優化。咱們在咱們框架裏添加詳細的啓動/暫停的性能錨點,收集數據,使用 catapult 查看器來定位熱點和阻塞線程間交互的。也能夠從開發者菜單下觸發開始對咱們應用的性能分析。
在RN中,代碼是在JavaScript線程中執行的。每次你要寫數據到磁盤,在一次網絡請求,或者取一些其餘原生的資源(如攝像機),你的代碼都須要調用原生模塊。當你要渲染力你的 React 組件,它們會被轉發到界面管理器的原生模塊中,它在主線程中來執行佈局和建立相應的視圖。橋協議來轉發請求到原生模塊和被回調到你的JS代碼(若是須要)。在RN中,全部原生的調用必須是異步的來避免阻塞主線程和JS線程。
在下面的事件組件的啓動可視化圖中,咱們能夠看到應用在 JS 隊列中運行,爲了顯示事件列表,觸發了相關的緩存讀取(在本地存儲隊列中被異步觸發)。一旦它取得了緩存數據,應用在 JS 隊列用 React 渲染事件單元格,接着又傳給柵格隊列來佈局和最終傳給主隊列來建立視圖顯示。這個例子展現了多個緩存讀取(組合成單個經常使用讀取操做能夠作到更快)和一些React在JS線程上的渲染操做能夠被統一合併。
下面是那些咱們在實施過程當中最重要的性能和時序安排的提高作法,同時配有對應代碼提交的連接。
幾個月前,事件主頁的啓動在 iPhone5 上須要2秒。通過咱們在RN上的大量性能優化工做,在倫敦,門洛帕克和紐約的RN,React和Relay團隊,事件主頁的啓動被加快了一倍。並且大部分咱們實施的優化是在RN的框架層的,這就意味着開發者們的RN應用也會自動得益於這些工做(當他們把應用遷移到最新版本的RN下
這些優化才僅僅是個開始:咱們會繼續在整個棧的各個部分都開展工做,從JavaScript代碼解析時間到數據拉取性能。同時,大家也能夠給社區貢獻,學習如何讓應用更快,在社區論壇提出你可能遇到的任何問題。QQ技術交流羣290551701