翻譯原文: React Native Performance: Do and Don’t
做者: amanhimselfjavascript
在使用一些框架例如React Native去實際開發移動端應用的時候,性能是一個重要的問題。React Native默認狀況下的性能是沒有問題的,可是在實際開發React Native的時候,咱們也可能會遇到一些性能相關的問題。java
這些問題是很難經過組件自己修復去解決的。在這篇文章中,咱們會提供一些建議來優化開發React Native遇到的一些性能問題。react
React Native在自帶的組件庫中提供了Image組件,能夠用例展現圖片。可是這個組件沒有解決如下這些問題的開箱即用的解決方案:git
React Native中的Image組件處理緩存圖片的時候會像web 瀏覽器同樣的行爲,會可能致使上面提到的問題。能夠經過使用第三方庫react-native-fast-image來解決上面的這些問題。這個庫在iOS和安卓上均可用而且可以有效的緩存圖片github
若是React Native APP依賴於使用大量的圖像,那麼優化圖像對於APP的性能是很重要的。若是圖片的尺寸沒有獲得合適的優化,渲染大量圖片會致使在設備上佔用大量的內存。這可能會致使APP崩潰web
一些能夠在React Native中有效優化圖片的方案包括:數據庫
React Native是基於React的庫而且處理組件渲染的形式相似於React.js。所以在React中可用的優化方法也適用於React Native。一個優化方法就是避免沒必要要的渲染,在函數組件中能夠經過使用React.memo()
來完成。json
React.memo
是被用來進行處理記憶化(memoization)。記憶化的理念是:若是一個組件接收相同的props超過一次,它將會使用以前一次緩存的props。而且函數組件只會進行一次渲染返回jsxreact-native
例以下面Parent組件和Child組件的例子。Parent組件有一個count的state變量,每次button點擊的時候更新count數組
當button點擊的時候,即便Child組件的props屬性text沒有改變,每次Parent組件渲染都會形成Child組件的從新渲染。Child組件沒有作任何和Parent組件有關的操做而僅僅是展現一些靜態文本。這個行爲能夠經過把Child組件用React.memo()
包着來進行優化
// Parent.js
const Parent = () => {
const [count, setCount] = useState(0);
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Button title='Press me' onPress={() => setCount(count + 1)} /> <Child text='Placeholder text' /> </View>
);
};
// Child.js
const Child = React.Memo(({ text }) => {
return <Text>{text}</Text>;
});
複製代碼
nativeDriver
React Native中有不少方法能夠寫動畫,最經常使用的方法就是使用Animated庫
Animated
Animated會在動畫執行以前,經過nativeDriver把動畫發送到原生bridge中,這有助於動畫獨立於被阻塞的JavaScript線程執行,動畫會執行比較流暢而不會丟幀
經過設置useNativeDriver的值爲true,能夠在Animated庫中使用nativeDriver。下面的例子就是在ScrollView組件的onScroll事件中使用useNativeDriver
<ScrollView
showsVerticalScrollIndicator={false}
scrollEventThrottle={1}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: animatedValue } } }],
{ useNativeDriver: true }
)}
>
// 組件的內容
</ScrollView>
複製代碼
React Native 0.62.0版本介紹了一個新的調試工具Flipper
。 這是一個給iOS、安卓和React Native使用的平臺 。它直接集成在原生代碼中,而且在React Native中開箱即用。
使用Flipper
調試app不須要遠程調試。須要一個本地鏈接的Metro實例來與React Native應用進行交互。它可經過React DevTools來檢查組件樹並檢查React組件的state和屬性。
它使用原生插件生態系統來調試iOS和Android應用程序。這些插件可用於設備日誌、崩潰報告、檢查網絡請求、檢查應用程序的本地數據庫、檢查緩存的圖像等。
Hermes是一個專爲移動端應用優化的開源javascript引擎。React Native 0.60.4版本以後,Hermes
在安卓也可用了。這有利於減小app的下載體積(安卓APK)、下降內存消耗和下降APP的可交互時間
在安卓APP中開啓Hermes引擎,須要打開build.gradle
而且修改以下:
def enableHermes = project.ext.react.get("enableHermes", true);
複製代碼
自React Native 0.64-rc.0版本後,Hermes也能用於iOS平臺。須要打開Podfile
而且修改以下:
use_react_native!(:path => config[:reactNativePath], :hermes_enabled => true
複製代碼
在Javascript應用包括React Native應用中,用console.log
調試是最經常使用的調試方法之一。然而,在構建React Native應用時,將console
語句留在源代碼中可能對JavaScript線程形成一些瓶頸。
一個解決方法就是使用babel-plugin-transform-remove-console
刪除掉console
語句。在終端經過下面的方法安裝
yarn add babel-plugin-transform-remove-console
複製代碼
而後修改 .babelrc
文件以下來刪除全部的console
語句
{
"env": {
"production": {
"plugins": ["transform-remove-console"]
}
}
}
複製代碼
有一些方法能夠在React Native中使用滾動列表。其中兩種最經常使用的方式就是使用ScrollView
和FlatList
組件
ScrollView
用起來很簡單,一般用於使用JavaScript的map()
函數遍歷一個數組。 例如:
<ScrollView>
{items.map(item => {
return <Item key={item.id.toString()} />;
})}
</ScrollView>
複製代碼
ScrollView
會一次性渲染全部的子組件,在須要渲染的子組件數量很少的時候會比較好用。但在處理大量的數據的時候會影響到APP的性能。
爲了解決渲染大量數據的狀況,React Native提供了一個FlatList
組件。這個組件可以懶加載子組件列表,這樣APP就不會消耗大量的內存
例如:
<FlatList
data={elements}
keyExtractor={item => `${items.id}`}
renderItem={({ item }) => <Item key={item.id.toString()} />}
/>
複製代碼
React Native是一個用於構建跨平臺應用的開源框架。它以JavaScript爲核心,並調用原生組件來構建移動端界面和功能。它會是一個高性能框架只要注意考慮到性能
本文正在參與「掘金 2021 春招闖關活動」, 點擊查看 活動詳情