2023 年优化 React Native 应用程序性能的终极指南
React Native 自 2015 年问世以来一直在突飞猛进地发展,相信这个跨平台应用程序开发框架已经超越了 Xamarin 和 Iconic。
React Native 为 DoM 事务使用了几种巧妙的方法,节省了刷新 UI 的时间。决策者了解拥有专门的 React Native 团队在构建 React Native 应用程序架构方面的重要性。但是,在扩展功能和操作时会出现某些瓶颈,例如内存泄漏会影响 React Native 应用程序的性能。
下面我们直接分析 React Native 性能优化的 9 个最佳实践。
提高 React Native 应用程序性能的 9 种方法
要提高 React Native 应用程序的性能,请遵循以下一些常见做法,从长远来看,这将使您受益匪浅。
1.使用爱马仕
为了使用 Hermes 和 React Native 获得最佳性能,您可以做一些事情:
在您的 React Native 项目中启用 Hermes:默认情况下,React Native 使用 JavaScriptCore 引擎来运行 JavaScript 代码。要改为使用 Hermes,您需要在项目的配置文件中启用它。启用后,Hermes 将用于编译和执行您的 JavaScript 代码,这可以带来更快的启动时间和更好的运行时性能。
使用最新版本的 React Native:由于 React Native 已经过优化以与 Hermes 配合使用,因此使用最新版本的 React Native 可以帮助您充分利用 Hermes。
优化代码:虽然 Hermes 可以提高 JavaScript 代码的性能,但编写高效的代码仍然很重要。这需要消除不必要的计算并减少访问 DOM 的次数。
测试您的应用:启用 Hermes 并优化您的代码后,请务必彻底测试您的应用,以确保其按预期运行。使用分析工具来识别任何性能瓶颈并相应地解决它们。
2. 渲染时避免匿名函数
在 React Native 中,在渲染组件时避免使用匿名函数通常是一个好习惯。这样做的原因是匿名函数会导致不必要的重新呈现,这会对您的应用程序的性能产生负面影响。
当你在组件的 render 方法中定义一个匿名函数时,它会在每次组件渲染时创建一个新的函数对象。这意味着即使该函数具有相同的行为和输出,它也会被视为一个新函数并会导致重新渲染。
为了避免这个问题,在 render 方法之外编写你的函数,并将它们作为 props 提供给你的组件。因此,函数对象只会生成一次,您的组件不会过度重新渲染。
从“反应”导入反应;从 'react-native' 导入 { TouchableOpacity, Text };const MyComponent = () => {
const handleClick = () => {
// 在这里处理点击事件
}
返回 (
< TouchableOpacity onPress={handleClick} >
<Text>点我</Text>
</TouchableOpacity >
);}导出默认的 MyComponent;
在上面的示例中,我们在 render 方法之外定义了 handleClick 函数,并将其作为 onPress 属性传递给 TouchableOpacity 组件。因此,不会有额外的效果图,函数对象只会产生一次。
通过在渲染组件时消除匿名方法,可以提高 React Native 应用程序的速度。
3. 优化 React-Native 内存使用
React Native 有许多内存优化技术,您可以使用它们来提高应用程序的速度并最大限度地减少其内存占用。这里有几个这样的例子:
虚拟化列表: React Native 提供了一个平面列表虚拟化长列表的组件,这意味着它只呈现当前在屏幕上可见的项目。这可以显着减少应用程序的内存使用量,尤其是在处理大量数据列表时。这是一个如何使用平面列表成分:
从“反应”导入反应;import { FlatList, Text } from 'react-native';const MyComponent = () => {
const data = [{ key: 'item1' }, { key: 'item2' }, { key: 'item3' }];
const renderItem = ({ item }) => (
{item.key}
);
返回 (
);}导出默认的 MyComponent;
图像缓存: React Native 提供了一种内置的图像缓存机制,可以帮助减少应用程序使用的内存量。默认情况下,React Native 在应用程序会话期间缓存图像。但是,您可以修改缓存行为以更好地满足程序的需求。这是一个例子:
从“反应”导入反应;从 'react-native' 导入 { Image };const MyComponent = () => {
const imageUrl = 'https://example.com/image.jpg';
返回 (
);}导出默认的 MyComponent;
想要构建一个打破障碍并与所有用户联系的 React Native 应用程序?聘请对可访问性原则有深刻理解并能完美实施它们的
React Native 开发人员。
4. 提高效率的缓存:昂贵组件的内存化
记忆化是 React Native 中的一种技术,在计算机编程中更普遍,它涉及根据函数的输入参数缓存函数调用的结果,这样如果使用相同的参数再次调用该函数,则可以返回缓存的结果重新计算结果。
Memoization 可用于使您的 React Native 应用程序更快,尤其是当您有大量数据流过它时。
性能提升:记忆化是一种内存优化技术,可用于提高应用程序的性能。它背后的想法是将昂贵的计算结果存储在一个对象中,然后在您再次需要它们时重用它们。这样,React Native 就不必在每次需要时都重新计算这些值。
代码可读性: Memoization 使您的代码更具可读性,因为它通过从函数主体中删除条件语句来降低复杂性。例如,假设你有这个功能
从“反应”中导入反应,{useMemo};const ExpensiveComponent = ({ data }) => {
const memoizedData = useMemo(() => {
// 对数据执行昂贵的计算
返回 data.map(item => item.name);
}, [数据]);
// 在组件渲染中使用 memoized 数据
返回 (
{memoizedData.join(', ')}
);};导出默认的 ExpensiveComponent;
🟠 React Native 中的记忆化
React Native 记忆化是一种用于存储昂贵计算结果的技术,以便您可以在以后的调用中重用它们。React Native 中有两种记忆策略:
► 纯组件
► 使用 useMemo Hook 进行记忆
要实现记忆化,您需要:
定义一个接受回调的函数(请求值时将调用的函数)。此函数应生成一个具有两个属性的对象:“缓存”和“键”。`cache` 属性包含缓存值(如果存在),否则为 null。`key` 属性包含一个唯一标识符,用于此特定调用的记忆函数。
将此新函数作为参数传递给您的原始函数调用。这会导致每个调用在被传递到其原始实现之前被包装在您的新包装函数中。
A。记忆与重构
从“反应”导入反应;import { View, Text } from 'react-native';从'recompose'导入{withMemo};const MyComponent = ({ name }) => {
console.log('正在渲染 MyComponent...');
返回 (
< 查看 >
< Text >你好,{name}!
);};const MemoizedMyComponent = withMemo(
({ name }) => name, // 记忆键
(props, nextProps) => props.name === nextProps.name, // 相等性检查)(我的组件);导出默认的 MemoizedMyComponent;
b. 重新选择记忆
从“反应”导入反应;import { View, Text } from 'react-native';从“重新选择”导入{createSelector};const MyComponent = ({ name, age }) => {
const greetingSelector = createSelector(
姓名 => 姓名,
年龄=>年龄,
(name, age) => `你好,${name}!你今年 ${age} 岁。`
);
const greeting = greetingSelector(姓名, 年龄);
console.log('正在渲染 MyComponent...');
返回 (
< 查看 >
{问候语}
);};导出默认的 MyComponent;
C。使用 Redux 进行记忆
在 Redux 中,您可以使用记忆来优化选择器的性能,选择器是计算来自 Redux 存储的派生数据的函数。
下面是一个如何使用 Redux 选择器进行记忆的例子:
从“重新选择”导入{createSelector};// 定义一个选择器来计算购物车中的商品总数const cartItemsSelector = state => state.cart.items;const cartItemCountSelector = createSelector(
购物车商品选择器,
items => items.reduce((count, item) => count + item.quantity, 0));// 定义一个使用购物车项目计数的组件const MyComponent = ({ cartItemCount }) => {
console.log('正在渲染 MyComponent...');
返回 (
购物车商品数:{cartItemCount}
);};// 将组件连接到 Redux store 并将购物车项目计数映射到 props常量 mapStateToProps = 状态 => ({
cartItemCount:cartItemCountSelector(状态)});导出默认连接(mapStateToProps)(MyComponent);
在上面的示例中,我们定义了一个名为 cartItemCountSelector 的选择器,用于计算购物车中的商品总数。我们使用 Reselect 库中的 createSelector 来根据购物车中的商品记住购物车商品数量的计算。
然后我们定义一个名为 MyComponent 的组件,它在其呈现中使用购物车项目计数。我们还使用 console.log 来记录组件渲染。
最后,我们使用 react-redux 包中的 connect 函数将组件连接到 Redux store,并使用 mapStateToProps 方法将购物车项目计数映射到 cartItemCount prop。
通过将记忆与 Redux 选择器结合使用,我们可以避免在 React Native 应用程序中对派生数据进行不必要的重新计算,并提高其性能。
5. 使用高阶组件来提高 React Native 应用程序的速度
高阶组件 (HOC) 是 React Native 中的一项有用功能,可用于通过重用代码和改进代码组织来提高应用程序速度。它们是接受组件作为输入并返回具有增强功能的新组件的函数。
以下是您可以使用 HOC 提高 React Native 应用程序性能的一些方法:
代码重用:HOC 通过将通用功能封装在可重用组件中来实现代码重用。这有助于减少构建和维护项目所需的代码量。
逻辑分离:HOC 有助于将业务逻辑与表示逻辑分离。您可以创建一个 HOC 来处理复杂的逻辑,并将其作为 prop 传递给您的展示组件。这有助于保持您的组件干净且易于阅读。
性能优化:HOC 可用于记忆昂贵的计算或防止不必要的重新渲染。这可以通过最大限度地减少每个渲染周期所需的工作量来提高应用程序的性能。
身份验证:HOC 可用于处理身份验证逻辑。例如,在显示组件之前,您可能会编写一个 HOC 来检查用户是否已获得授权。
数据获取:HOC 也可用于从 API 获取数据。您可以创建一个 HOC 来获取数据并将其作为 prop 传递给您的组件。
例子:
从“反应”中导入反应,{useState,useEffect};import { View, Text } from 'react-native';const withDataFetching = (WrappedComponent, dataSource) => {
const WithDataFetching = (props) => {
const [数据, setData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState('');
使用效果(()=> {
setIsLoading(真);
获取(数据源)
.then(响应=> {
如果(响应.ok){
返回响应.json();
} 别的 {
throw new Error('出错了');
}
})
.then(数据=> {
设置数据(数据);
setIsLoading(假);
})
.catch(错误=> {
设置错误(错误);
setIsLoading(假);
});
}, []);
返回 (
);
}
返回 WithDataFetching;};导出默认 withDataFetching;
在这个功能组件实现中,使用了useState hook来管理数据的状态,isLoading和error。当组件安装时,useEffect 挂钩检索数据并使用响应更新状态。最后,使用扩展语法,返回 WrappedComponent 状态和作为道具传递的道具。
6. 避免将内联函数作为 props 传递
在 React Native 中,将内联函数作为 props 传递可能会导致不必要的组件重新渲染并降低性能。这是因为在每次渲染时都会重新创建内联函数,即使它们的实现保持不变,这可能会导致子组件不必要地重新渲染。
这是一个示例,说明将内联函数作为 prop 传递如何导致重新渲染:
在上面的示例中,我们定义了一个名为 MyComponent 的功能组件,它使用 useState 挂钩来维护计数状态。我们还定义了一个 Button 组件,它在单击时增加计数状态,使用内联函数作为 onPress 属性。
然而,因为在每次渲染时都会重新创建内联函数,所以单击按钮将导致 MyComponent 重新渲染,即使它的实现没有改变。这可能会造成浪费并降低应用程序的性能。
为避免此问题,建议单独定义函数并将它们作为 props 传递,而不是内联定义它们。这样,函数将只创建一次并在多个渲染中重复使用,这有助于 React Native 性能优化。
下面是一个如何单独定义函数并将其作为 prop 传递的示例:
从“反应”中导入反应,{useState};从'react-native'导入{Button};const MyComponent = () => {
const [count, setCount] = useState(0);
const handleIncrement = () => {
设置计数(计数 + 1);
};
console.log('正在渲染 MyComponent...');
返回 (
);};导出默认的 MyComponent;
在上面的示例中,我们单独定义了 handleIncrement 函数并将其作为 Button 组件的 onPress prop 传递。因为该函数是在组件渲染之外定义的,它只会被创建一次并在多个渲染中重复使用,这有助于优化 React Native 应用程序的性能。
7. 为 React Native 应用性能优化 JSON 数据
移动应用程序总是需要从服务或远程 URL 加载资源,为了完成此类操作,程序员会发出获取请求以从该服务器提取数据。
从私有和公共 API 获取的数据以具有某种复合嵌套对象的 JSON 形式返回。通常,大多数程序员存储相同的 JSON 数据以供本地离线访问,并且性能受到影响,因为 JS 应用程序渲染 JSON 数据很慢。
因此,建议在渲染之前将原始 JSON 数据转换为更简单的对象。
获取('SomeURL',{
方法:'POST',
标题:{
接受:'应用程序/json',
'内容类型':'应用程序/ json',
},
正文:JSON.stringify({
firstParam: '你的价值',
secondParam: '你的其他价值',
}),}).then((response) => response.json())
.then((responseJson) => {
// 使用 JSON.parse 方法转换对象中的响应
var response = JSON.parse(responseJson);
返回响应;
})
.catch((错误) => {
控制台错误(错误);
})
8.使用NativeDriver动画
React Native 中的动画看起来不错并且易于创建。由于动画库允许您批准本机驱动程序,因此它会在动画开始之前通过桥将动画发送到本机端。
动画将独立于阻塞的 JavaScript 线程执行主线程;它将带来更流畅的体验和更少的帧丢失。
将使用本机驱动程序更改为动画配置。这就是常规动画的执行方式;
JavaScript 驱动程序使用 requestAnimationFrame 在每一帧上执行
计算中间值并将其传递给视图
使用 setNativeProps 更新视图
JS通过bridge将这些变化发送给原生环境
本机更新 UIView 或 Android.View。
但是,Native Driver Animation 是这样工作的。
本机动画驱动程序使用 CADisplayLink 或 android.view.Choreographer 在每一帧上执行
计算中间值并将其传递给视图
UIView/android.View 已更新。
例子 :
动画.timing(
this.state.fadeAnim, {
到值:1,
userNativeDriver:真,
}
)。开始()< Animated.ScrollView // <-- 使用动画滚动视图包装器
scrollEventThrottle={1} // <-- 在这里使用 1 以确保不会错过任何事件
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: this.state.animatedValue } } }],
{ useNativeDriver: true } // <-- 添加这个
)}>
{内容}< /Animated.ScrollView >
利用我们以结果为导向的 React Native 开发服务来摆脱技术难题。
作为最著名的React Native 开发公司,我们将帮助您构建卓越的移动应用程序,引导您进入 Android Play 和 iOS 应用程序商店。
9. 减小应用程序大小
React Native 使用外部和组件形式库来影响应用程序的大小。要减小尺寸,您必须优化资源,使用 ProGaurd 为不同的设备架构创建不同尺寸的应用程序,并压缩图形元素,即图像。
您可以按照以下常见做法来减小应用程序大小和图像大小以提高React Native应用程序速度:
将组件从原生领域移动到 React Nativerealm。
JavaScript 端的组件使用桥接器与 Native 端进行通信。
减少桥上的负载并提高 React Native 应用程序性能。
在使用之前检查开源库的稳定性。库中的样板代码通常会降低渲染性能。
某些组件在与 Native 端通信时会大量使用消息队列,因此您不应将它们传递给主线程。
使用较小尺寸的图像并使用 PNG 而不是 JPG。
将图像转换为 WebP 格式。
利用 React NativeJS 线程和导航器转换。
使用 .webp 格式将 CodePush 包大小减少 66%。
最后的话
如果您确信您的用户需要您现有应用程序中的这些个性化功能,那么 React Native 是您最好的朋友。您所需要的只是一家著名的 React Native 开发公司,通过将这些实践实施到您的应用程序来提高 React Native 的应用程序性能。
Bacancy Technology 是一家全球知名的软件开发公司和一站式解决方案,聘请 React Native 开发人员将您的想法转化为可行的业务解决方案。我们的离岸 React Native 应用程序开发人员精通了解全球客户的 MVP,并成功交付了广泛的产品。通过使用自定义功能优化您的应用程序,提升您的 React Native 应用程序性能。
言鼎科技主做软件开发,微信小程序,网站开发,软件外包,手机APP开发。如有需要记得联系我们!