React-Native知識點相關

React-Native相關

 

一,為什麼要使用React-native

 

  1. Hybrird的首屏時間太慢,白屏太久,影響用戶體驗;
  2. 原生native開發成本較高;

 

這裡補充一點Webview的性能優化:

 

Hybrid最大的問題就是首次打開白屏時間較長,原因是Webview初始化時耗時較長,等到初始化完成後,再去請求頁面資源數據就更久了,這是一個串行的過程,所以比較久。

 

因此針對這一點,可以做以下優化:

 

  1. 在使用前預先初始化好Webview,比如客戶端剛啟動的時候,就可以開始初始化一個全局的Webview備用了;
  2. 在初始化的同時,通過native來完成一些網絡請求等過程,使得變為並行;
  3. DNS採用和客戶端API相同的域名,因為DNS會在系統級別進行緩存,這樣減少Webview的DNS解析時間;

 

儘管如此,白屏時間依然達不到我們期待的1s之內,因此果斷選擇了RN去重構!

 

 

 

 

二,什麼是JSBridge,解釋一下它的原理?

 

JSBridge一般用在Web的Hybrid解決方案以及React-Native上,有了它可以利用Web API去調用Native的功能。它的核心是構建native和非native之間的消息通信的通道,而且是雙向通道。(所謂的雙向通道就是JS向Native發送信息,調用相關功能,通知當前JS的狀態,然後Native再回溯調用結果,消息推送,返回Native的狀態。)

 

Javascript是運行在一個單獨的JS Context中(比如Webkit和JS Core),和原生的運行環境是隔離開來的,因此這種情況與RPC(遠程過程調用)通信有點類似,可以把JS當做RPC客戶端,Native當做RPC服務端,因此JSBridge要實現的主要邏輯就是:通信調用和句柄解析調用。

 

1,通信調用的原理:

 

  1. JavaScript調用Native一般使用的是注入API的方式
  2. Native調用JavaScript直接執行拼接好的Javascript代碼即可

 

2,句柄解析調用的原理:

 

其實就是句柄與功能的對應關係,將句柄抽象為BridgeName(橋名),最終演化成一個BridgeName對應一個Native功能或一類消息。

 

最後Native的callback,實際上就是利用一個唯一標識callbackId來進行回調。JavaScript里定義好函數以及唯一標識callbackId,然後將這個id傳給Native,Native回調的時候將返回值和callbackId再回傳給JavaScript,類似於Jsonp的實現。

 

 

三,RN是怎麼運行的?

 

RN本質上就是JavascriptCore + React + JSBridge

 

RN會把應用代碼編譯成兩個js bundle文件,一個index.ios.bundle.js,一個index.android.bundle.js,這兩個文件會在內置的JS運行環境里執行,IOSJS Core,Androidwebkit,JS引擎是JavaScriptCore

UI渲染部分,利用RN底層的React,將JSX轉換成虛擬DOM,然後通過diff算法生成一個JSON文件,再藉助JSBridge調用Native的API根據這個JSON文件進行繪製,最終渲染到屏幕上。

 

四,Hermes了解么?

 

Hermes是Facebook自研的一款JavaScript引擎,用來優化安卓上的react native,主要優化點是3個:

  1. TTI
  2. APP的下載大小
  3. 內存佔用

 

 

五,RN性能優化?

 

1,減少re-render

 

  1. shouldComponentUpdate
  2. React.memo
  3. PureComponent

 

2,利用Fragment避免多層View嵌套,特別是封裝組件的時候

 

3,加載圖片可以使用WebP格式,圖片體積明顯減少

 

4,最重要的動畫性能優化:

 

一般大部分設備,只要保證60fps的幀率就可以了,首先要知道為什麼動畫會卡頓,原因就是在原生應用里,UI是由特定的繪製UI的線程控制的,而JS線程需要去通知UI線程進行繪製,但這個過程是異步的,如果JS線程上任務較多,就很難保證每一幀都是及時渲染的。因此為了動畫不卡,需要考慮兩點:

 

  1. 減少JS線程和UI線程之間的異步通信
  2. 減少JS線程上的計算

 

優化手段有:

  1. useNativeDrive設為true,這個屬性是開啟原生驅動,利用原生代碼在UI線程上執行繪畫,不需要持續通過JS線程
  2. setNativeProps,這個等同於直接修改瀏覽器的DOM
  3. 藉助一些優秀的第三方animate動畫庫,比如react-native-reanimated,基本思路也是減少JS線程的計算和通信,利用原生UI線程進行繪製

 

5,針對ListItems 優化,使用getItemLayout提前計算高度

  

六,RN調試工具?

 

1,react-native官方調試工具 (command + D

2,react-devtools

3,XCode里,Profile工具