2023 年優(yōu)化 React Native 應(yīng)用程序性能的終極指南

yanding 2023-06-22 1392

React Native 自 2015 年問世以來一直在突飛猛進(jìn)地發(fā)展,相信這個跨平臺應(yīng)用程序開發(fā)框架已經(jīng)超越了 Xamarin 和 Iconic。

React Native 為 DoM 事務(wù)使用了幾種巧妙的方法,節(jié)省了刷新 UI 的時間。決策者了解擁有專門的 React Native 團(tuán)隊在構(gòu)建 React Native 應(yīng)用程序架構(gòu)方面的重要性。但是,在擴展功能和操作時會出現(xiàn)某些瓶頸,例如內(nèi)存泄漏會影響 React Native 應(yīng)用程序的性能。

下面我們直接分析 React Native 性能優(yōu)化的 9 個最佳實踐。

提高 React Native 應(yīng)用程序性能的 9 種方法

要提高 React Native 應(yīng)用程序的性能,請遵循以下一些常見做法,從長遠(yuǎn)來看,這將使您受益匪淺。

1.使用愛馬仕

為了使用 Hermes 和 React Native 獲得最佳性能,您可以做一些事情:

  • 在您的 React Native 項目中啟用 Hermes:默認(rèn)情況下,React Native 使用 JavaScriptCore 引擎來運行 JavaScript 代碼。要改為使用 Hermes,您需要在項目的配置文件中啟用它。啟用后,Hermes 將用于編譯和執(zhí)行您的 JavaScript 代碼,這可以帶來更快的啟動時間和更好的運行時性能。

  • 使用最新版本的 React Native:由于 React Native 已經(jīng)過優(yōu)化以與 Hermes 配合使用,因此使用最新版本的 React Native 可以幫助您充分利用 Hermes。

  • 優(yōu)化代碼:雖然 Hermes 可以提高 JavaScript 代碼的性能,但編寫高效的代碼仍然很重要。這需要消除不必要的計算并減少訪問 DOM 的次數(shù)。

  • 測試您的應(yīng)用:啟用 Hermes 并優(yōu)化您的代碼后,請務(wù)必徹底測試您的應(yīng)用,以確保其按預(yù)期運行。使用分析工具來識別任何性能瓶頸并相應(yīng)地解決它們。

2. 渲染時避免匿名函數(shù)

在 React Native 中,在渲染組件時避免使用匿名函數(shù)通常是一個好習(xí)慣。這樣做的原因是匿名函數(shù)會導(dǎo)致不必要的重新呈現(xiàn),這會對您的應(yīng)用程序的性能產(chǎn)生負(fù)面影響。

當(dāng)你在組件的 render 方法中定義一個匿名函數(shù)時,它會在每次組件渲染時創(chuàng)建一個新的函數(shù)對象。這意味著即使該函數(shù)具有相同的行為和輸出,它也會被視為一個新函數(shù)并會導(dǎo)致重新渲染。

為了避免這個問題,在 render 方法之外編寫你的函數(shù),并將它們作為 props 提供給你的組件。因此,函數(shù)對象只會生成一次,您的組件不會過度重新渲染。

2023 年優(yōu)化 React Native 應(yīng)用程序性能的終極指南
從“反應(yīng)”導(dǎo)入反應(yīng);從 'react-native' 導(dǎo)入 { TouchableOpacity, Text };const MyComponent = () => {
 const handleClick = () => {
   // 在這里處理點擊事件
 }
 返回 (
   < TouchableOpacity onPress={handleClick} >
     <Text>點我</Text>
   </TouchableOpacity >
 );}導(dǎo)出默認(rèn)的 MyComponent;

在上面的示例中,我們在 render 方法之外定義了 handleClick 函數(shù),并將其作為 onPress 屬性傳遞給 TouchableOpacity 組件。因此,不會有額外的效果圖,函數(shù)對象只會產(chǎn)生一次。

通過在渲染組件時消除匿名方法,可以提高 React Native 應(yīng)用程序的速度。

3. 優(yōu)化 React-Native 內(nèi)存使用

React Native 有許多內(nèi)存優(yōu)化技術(shù),您可以使用它們來提高應(yīng)用程序的速度并最大限度地減少其內(nèi)存占用。這里有幾個這樣的例子:
虛擬化列表: React Native 提供了一個
平面列表虛擬化長列表的組件,這意味著它只呈現(xiàn)當(dāng)前在屏幕上可見的項目。這可以顯著減少應(yīng)用程序的內(nèi)存使用量,尤其是在處理大量數(shù)據(jù)列表時。這是一個如何使用平面列表成分:

2023 年優(yōu)化 React Native 應(yīng)用程序性能的終極指南
從“反應(yīng)”導(dǎo)入反應(yīng);import { FlatList, Text } from 'react-native';const MyComponent = () => {
 const data = [{ key: 'item1' }, { key: 'item2' }, { key: 'item3' }];
 const renderItem = ({ item }) => (
   {item.key}
 );
 返回 (
   
 );}導(dǎo)出默認(rèn)的 MyComponent;

圖像緩存: React Native 提供了一種內(nèi)置的圖像緩存機制,可以幫助減少應(yīng)用程序使用的內(nèi)存量。默認(rèn)情況下,React Native 在應(yīng)用程序會話期間緩存圖像。但是,您可以修改緩存行為以更好地滿足程序的需求。這是一個例子:

2023 年優(yōu)化 React Native 應(yīng)用程序性能的終極指南
從“反應(yīng)”導(dǎo)入反應(yīng);從 'react-native' 導(dǎo)入 { Image };const MyComponent = () => {
 const imageUrl = 'https://example.com/image.jpg';
 返回 (
   
 );}導(dǎo)出默認(rèn)的 MyComponent;

想要構(gòu)建一個打破障礙并與所有用戶聯(lián)系的 React Native 應(yīng)用程序?聘請對可訪問性原則有深刻理解并能完美實施它們的
React Native 開發(fā)人員。

4. 提高效率的緩存:昂貴組件的內(nèi)存化

記憶化是 React Native 中的一種技術(shù),在計算機編程中更普遍,它涉及根據(jù)函數(shù)的輸入?yún)?shù)緩存函數(shù)調(diào)用的結(jié)果,這樣如果使用相同的參數(shù)再次調(diào)用該函數(shù),則可以返回緩存的結(jié)果重新計算結(jié)果。

Memoization 可用于使您的 React Native 應(yīng)用程序更快,尤其是當(dāng)您有大量數(shù)據(jù)流過它時。

性能提升:記憶化是一種內(nèi)存優(yōu)化技術(shù),可用于提高應(yīng)用程序的性能。它背后的想法是將昂貴的計算結(jié)果存儲在一個對象中,然后在您再次需要它們時重用它們。這樣,React Native 就不必在每次需要時都重新計算這些值。

代碼可讀性: Memoization 使您的代碼更具可讀性,因為它通過從函數(shù)主體中刪除條件語句來降低復(fù)雜性。例如,假設(shè)你有這個功能

2023 年優(yōu)化 React Native 應(yīng)用程序性能的終極指南
從“反應(yīng)”中導(dǎo)入反應(yīng),{useMemo};const ExpensiveComponent = ({ data }) => {
 const memoizedData = useMemo(() => {
   // 對數(shù)據(jù)執(zhí)行昂貴的計算
   返回 data.map(item => item.name);
 }, [數(shù)據(jù)]);
 // 在組件渲染中使用 memoized 數(shù)據(jù)
 返回 (
   {memoizedData.join(', ')}
 );};導(dǎo)出默認(rèn)的 ExpensiveComponent;

?? React Native 中的記憶化
React Native 記憶化是一種用于存儲昂貴計算結(jié)果的技術(shù),以便您可以在以后的調(diào)用中重用它們。React Native 中有兩種記憶策略:
? 純組件
? 使用 useMemo Hook 進(jìn)行記憶

要實現(xiàn)記憶化,您需要:

  • 定義一個接受回調(diào)的函數(shù)(請求值時將調(diào)用的函數(shù))。此函數(shù)應(yīng)生成一個具有兩個屬性的對象:“緩存”和“鍵”。`cache` 屬性包含緩存值(如果存在),否則為 null。`key` 屬性包含一個唯一標(biāo)識符,用于此特定調(diào)用的記憶函數(shù)。

  • 將此新函數(shù)作為參數(shù)傳遞給您的原始函數(shù)調(diào)用。這會導(dǎo)致每個調(diào)用在被傳遞到其原始實現(xiàn)之前被包裝在您的新包裝函數(shù)中。

A。記憶與重構(gòu)

2023 年優(yōu)化 React Native 應(yīng)用程序性能的終極指南
從“反應(yīng)”導(dǎo)入反應(yīng);import { View, Text } from 'react-native';從'recompose'導(dǎo)入{withMemo};const MyComponent = ({ name }) => {
 console.log('正在渲染 MyComponent...');
 返回 (
   < 查看 >
     < Text >你好,{name}!
   
 );};const MemoizedMyComponent = withMemo(
 ({ name }) => name, // 記憶鍵
 (props, nextProps) => props.name === nextProps.name, // 相等性檢查)(我的組件);導(dǎo)出默認(rèn)的 MemoizedMyComponent;

b. 重新選擇記憶

2023 年優(yōu)化 React Native 應(yīng)用程序性能的終極指南
從“反應(yīng)”導(dǎo)入反應(yīng);import { View, Text } from 'react-native';從“重新選擇”導(dǎo)入{createSelector};const MyComponent = ({ name, age }) => {
 const greetingSelector = createSelector(
   姓名 => 姓名,
   年齡=>年齡,
   (name, age) => `你好,${name}!你今年 ${age} 歲。`
 );
 const greeting = greetingSelector(姓名, 年齡);
 console.log('正在渲染 MyComponent...');
 返回 (
   < 查看 >
     {問候語}
   
 );};導(dǎo)出默認(rèn)的 MyComponent;

C。使用 Redux 進(jìn)行記憶
在 Redux 中,您可以使用記憶來優(yōu)化選擇器的性能,選擇器是計算來自 Redux 存儲的派生數(shù)據(jù)的函數(shù)。

下面是一個如何使用 Redux 選擇器進(jìn)行記憶的例子:

2023 年優(yōu)化 React Native 應(yīng)用程序性能的終極指南
從“重新選擇”導(dǎo)入{createSelector};// 定義一個選擇器來計算購物車中的商品總數(shù)const cartItemsSelector = state => state.cart.items;const cartItemCountSelector = createSelector(
 購物車商品選擇器,
 items => items.reduce((count, item) => count + item.quantity, 0));// 定義一個使用購物車項目計數(shù)的組件const MyComponent = ({ cartItemCount }) => {
 console.log('正在渲染 MyComponent...');
 返回 (
   購物車商品數(shù):{cartItemCount}
 );};// 將組件連接到 Redux store 并將購物車項目計數(shù)映射到 props常量 mapStateToProps = 狀態(tài) => ({
 cartItemCount:cartItemCountSelector(狀態(tài))});導(dǎo)出默認(rèn)連接(mapStateToProps)(MyComponent);

在上面的示例中,我們定義了一個名為 cartItemCountSelector 的選擇器,用于計算購物車中的商品總數(shù)。我們使用 Reselect 庫中的 createSelector 來根據(jù)購物車中的商品記住購物車商品數(shù)量的計算。

然后我們定義一個名為 MyComponent 的組件,它在其呈現(xiàn)中使用購物車項目計數(shù)。我們還使用 console.log 來記錄組件渲染。

最后,我們使用 react-redux 包中的 connect 函數(shù)將組件連接到 Redux store,并使用 mapStateToProps 方法將購物車項目計數(shù)映射到 cartItemCount prop。

通過將記憶與 Redux 選擇器結(jié)合使用,我們可以避免在 React Native 應(yīng)用程序中對派生數(shù)據(jù)進(jìn)行不必要的重新計算,并提高其性能。

5. 使用高階組件來提高 React Native 應(yīng)用程序的速度

高階組件 (HOC) 是 React Native 中的一項有用功能,可用于通過重用代碼和改進(jìn)代碼組織來提高應(yīng)用程序速度。它們是接受組件作為輸入并返回具有增強功能的新組件的函數(shù)。

以下是您可以使用 HOC 提高 React Native 應(yīng)用程序性能的一些方法:

  • 代碼重用:HOC 通過將通用功能封裝在可重用組件中來實現(xiàn)代碼重用。這有助于減少構(gòu)建和維護(hù)項目所需的代碼量。

  • 邏輯分離:HOC 有助于將業(yè)務(wù)邏輯與表示邏輯分離。您可以創(chuàng)建一個 HOC 來處理復(fù)雜的邏輯,并將其作為 prop 傳遞給您的展示組件。這有助于保持您的組件干凈且易于閱讀。

  • 性能優(yōu)化:HOC 可用于記憶昂貴的計算或防止不必要的重新渲染。這可以通過最大限度地減少每個渲染周期所需的工作量來提高應(yīng)用程序的性能。

  • 身份驗證:HOC 可用于處理身份驗證邏輯。例如,在顯示組件之前,您可能會編寫一個 HOC 來檢查用戶是否已獲得授權(quán)。

  • 數(shù)據(jù)獲?。篐OC 也可用于從 API 獲取數(shù)據(jù)。您可以創(chuàng)建一個 HOC 來獲取數(shù)據(jù)并將其作為 prop 傳遞給您的組件。

例子:

2023 年優(yōu)化 React Native 應(yīng)用程序性能的終極指南
從“反應(yīng)”中導(dǎo)入反應(yīng),{useState,useEffect};import { View, Text } from 'react-native';const withDataFetching = (WrappedComponent, dataSource) => {
 const WithDataFetching = (props) => {
   const [數(shù)據(jù), setData] = useState([]);
   const [isLoading, setIsLoading] = useState(false);
   const [error, setError] = useState('');
   使用效果(()=> {
     setIsLoading(真);
     獲?。〝?shù)據(jù)源)
       .then(響應(yīng)=> {
         如果(響應(yīng).ok){
           返回響應(yīng).json();
         } 別的 {
           throw new Error('出錯了');
         }
       })
       .then(數(shù)據(jù)=> {
         設(shè)置數(shù)據(jù)(數(shù)據(jù));
         setIsLoading(假);
       })
       .catch(錯誤=> {
         設(shè)置錯誤(錯誤);
         setIsLoading(假);
       });
   }, []);
   返回 (
     
   );
 }
 
 返回 WithDataFetching;};導(dǎo)出默認(rèn) withDataFetching;

在這個功能組件實現(xiàn)中,使用了useState hook來管理數(shù)據(jù)的狀態(tài),isLoading和error。當(dāng)組件安裝時,useEffect 掛鉤檢索數(shù)據(jù)并使用響應(yīng)更新狀態(tài)。最后,使用擴展語法,返回 WrappedComponent 狀態(tài)和作為道具傳遞的道具。

6. 避免將內(nèi)聯(lián)函數(shù)作為 props 傳遞

在 React Native 中,將內(nèi)聯(lián)函數(shù)作為 props 傳遞可能會導(dǎo)致不必要的組件重新渲染并降低性能。這是因為在每次渲染時都會重新創(chuàng)建內(nèi)聯(lián)函數(shù),即使它們的實現(xiàn)保持不變,這可能會導(dǎo)致子組件不必要地重新渲染。

這是一個示例,說明將內(nèi)聯(lián)函數(shù)作為 prop 傳遞如何導(dǎo)致重新渲染:

2023 年優(yōu)化 React Native 應(yīng)用程序性能的終極指南

在上面的示例中,我們定義了一個名為 MyComponent 的功能組件,它使用 useState 掛鉤來維護(hù)計數(shù)狀態(tài)。我們還定義了一個 Button 組件,它在單擊時增加計數(shù)狀態(tài),使用內(nèi)聯(lián)函數(shù)作為 onPress 屬性。

然而,因為在每次渲染時都會重新創(chuàng)建內(nèi)聯(lián)函數(shù),所以單擊按鈕將導(dǎo)致 MyComponent 重新渲染,即使它的實現(xiàn)沒有改變。這可能會造成浪費并降低應(yīng)用程序的性能。

為避免此問題,建議單獨定義函數(shù)并將它們作為 props 傳遞,而不是內(nèi)聯(lián)定義它們。這樣,函數(shù)將只創(chuàng)建一次并在多個渲染中重復(fù)使用,這有助于 React Native 性能優(yōu)化。

下面是一個如何單獨定義函數(shù)并將其作為 prop 傳遞的示例:

2023 年優(yōu)化 React Native 應(yīng)用程序性能的終極指南
從“反應(yīng)”中導(dǎo)入反應(yīng),{useState};從'react-native'導(dǎo)入{Button};const MyComponent = () => {
 const [count, setCount] = useState(0);
 const handleIncrement = () => {
   設(shè)置計數(shù)(計數(shù) + 1);
 };
 console.log('正在渲染 MyComponent...');
 返回 (
   
 );};導(dǎo)出默認(rèn)的 MyComponent;

在上面的示例中,我們單獨定義了 handleIncrement 函數(shù)并將其作為 Button 組件的 onPress prop 傳遞。因為該函數(shù)是在組件渲染之外定義的,它只會被創(chuàng)建一次并在多個渲染中重復(fù)使用,這有助于優(yōu)化 React Native 應(yīng)用程序的性能。

7. 為 React Native 應(yīng)用性能優(yōu)化 JSON 數(shù)據(jù)

移動應(yīng)用程序總是需要從服務(wù)或遠(yuǎn)程 URL 加載資源,為了完成此類操作,程序員會發(fā)出獲取請求以從該服務(wù)器提取數(shù)據(jù)。

從私有和公共 API 獲取的數(shù)據(jù)以具有某種復(fù)合嵌套對象的 JSON 形式返回。通常,大多數(shù)程序員存儲相同的 JSON 數(shù)據(jù)以供本地離線訪問,并且性能受到影響,因為 JS 應(yīng)用程序渲染 JSON 數(shù)據(jù)很慢。

因此,建議在渲染之前將原始 JSON 數(shù)據(jù)轉(zhuǎn)換為更簡單的對象。

2023 年優(yōu)化 React Native 應(yīng)用程序性能的終極指南
獲?。?#39;SomeURL',{
方法:'POST',
標(biāo)題:{
   接受:'應(yīng)用程序/json',
  '內(nèi)容類型':'應(yīng)用程序/ json',
},
正文:JSON.stringify({
  firstParam: '你的價值',
  secondParam: '你的其他價值',
}),}).then((response) => response.json())
 .then((responseJson) => {
      // 使用 JSON.parse 方法轉(zhuǎn)換對象中的響應(yīng)
      var response = JSON.parse(responseJson);
      返回響應(yīng);
    })
  .catch((錯誤) => {
    控制臺錯誤(錯誤);
  })

8.使用NativeDriver動畫

React Native 中的動畫看起來不錯并且易于創(chuàng)建。由于動畫庫允許您批準(zhǔn)本機驅(qū)動程序,因此它會在動畫開始之前通過橋?qū)赢嫲l(fā)送到本機端。

動畫將獨立于阻塞的 JavaScript 線程執(zhí)行主線程;它將帶來更流暢的體驗和更少的幀丟失。

將使用本機驅(qū)動程序更改為動畫配置。這就是常規(guī)動畫的執(zhí)行方式;

  • JavaScript 驅(qū)動程序使用 requestAnimationFrame 在每一幀上執(zhí)行

  • 計算中間值并將其傳遞給視圖

  • 使用 setNativeProps 更新視圖

  • JS通過bridge將這些變化發(fā)送給原生環(huán)境

  • 本機更新 UIView 或 Android.View。

但是,Native Driver Animation 是這樣工作的。

  • 本機動畫驅(qū)動程序使用 CADisplayLink 或 android.view.Choreographer 在每一幀上執(zhí)行

  • 計算中間值并將其傳遞給視圖

  • UIView/android.View 已更新。

2023 年優(yōu)化 React Native 應(yīng)用程序性能的終極指南
例子 :
動畫.timing(
           this.state.fadeAnim, {
           到值:1,
           userNativeDriver:真,
          }
       )。開始()< Animated.ScrollView // <-- 使用動畫滾動視圖包裝器
 scrollEventThrottle={1} // <-- 在這里使用 1 以確保不會錯過任何事件
 onScroll={Animated.event(
   [{ nativeEvent: { contentOffset: { y: this.state.animatedValue } } }],
   { useNativeDriver: true } // <-- 添加這個
 )}>
 {內(nèi)容}< /Animated.ScrollView >

利用我們以結(jié)果為導(dǎo)向的 React Native 開發(fā)服務(wù)來擺脫技術(shù)難題。
作為最著名的
React Native 開發(fā)公司,我們將幫助您構(gòu)建卓越的移動應(yīng)用程序,引導(dǎo)您進(jìn)入 Android Play 和 iOS 應(yīng)用程序商店。

9. 減小應(yīng)用程序大小

React Native 使用外部和組件形式庫來影響應(yīng)用程序的大小。要減小尺寸,您必須優(yōu)化資源,使用 ProGaurd 為不同的設(shè)備架構(gòu)創(chuàng)建不同尺寸的應(yīng)用程序,并壓縮圖形元素,即圖像。

您可以按照以下常見做法來減小應(yīng)用程序大小和圖像大小以提高React Native應(yīng)用程序速度:

  • 將組件從原生領(lǐng)域移動到 React Nativerealm。

  • JavaScript 端的組件使用橋接器與 Native 端進(jìn)行通信。

  • 減少橋上的負(fù)載并提高 React Native 應(yīng)用程序性能。

  • 在使用之前檢查開源庫的穩(wěn)定性。庫中的樣板代碼通常會降低渲染性能。

  • 某些組件在與 Native 端通信時會大量使用消息隊列,因此您不應(yīng)將它們傳遞給主線程。

  • 使用較小尺寸的圖像并使用 PNG 而不是 JPG。

  • 將圖像轉(zhuǎn)換為 WebP 格式。

  • 利用 React NativeJS 線程和導(dǎo)航器轉(zhuǎn)換。

  • 使用 .webp 格式將 CodePush 包大小減少 66%。

最后的話

如果您確信您的用戶需要您現(xiàn)有應(yīng)用程序中的這些個性化功能,那么 React Native 是您最好的朋友。您所需要的只是一家著名的 React Native 開發(fā)公司,通過將這些實踐實施到您的應(yīng)用程序來提高 React Native 的應(yīng)用程序性能。

Bacancy Technology 是一家全球知名的軟件開發(fā)公司和一站式解決方案,聘請 React Native 開發(fā)人員將您的想法轉(zhuǎn)化為可行的業(yè)務(wù)解決方案。我們的離岸 React Native 應(yīng)用程序開發(fā)人員精通了解全球客戶的 MVP,并成功交付了廣泛的產(chǎn)品。通過使用自定義功能優(yōu)化您的應(yīng)用程序,提升您的 React Native 應(yīng)用程序性能。

言鼎科技主做軟件開發(fā),微信小程序,網(wǎng)站開發(fā),軟件外包,手機APP開發(fā)。如有需要記得聯(lián)系我們!

The End