在使用一些框架例如React Native去实际开发移动端应用的时候,性能是一个重要的问题。React Native默认情况下的性能是没有问题的,但是在实际开发React Native的时候,我们也可能会遇到一些性能相关的问题。
这些问题是很难通过组件本身修复去解决的。在这篇文章中,我们会提供一些建议来优化开发React Native遇到的一些性能问题。
使用Image缓存解决方案
React Native在自带的组件库中提供了Image组件,可以用例展示图片。但是这个组件没有解决以下这些问题的开箱即用的解决方案:
- 屏幕中渲染大量图片
- 一般情况下性能比较低
- 从缓存中加载性能比较低
- 会有加载闪烁
React Native中的Image组件处理缓存图片的时候会像web 浏览器一样的行为,会可能导致上面提到的问题。可以通过使用第三方库react-native-fast-image来解决上面的这些问题。这个库在iOS和安卓上都可用并且能够有效的缓存图片
使用适当大小的图片
如果React Native APP依赖于使用大量的图像,那么优化图像对于APP的性能是很重要的。如果图片的尺寸没有得到合适的优化,渲染大量图片会导致在设备上占用大量的内存。这可能会导致APP崩溃
一些可以在React Native中有效优化图片的方案包括:
- 使用PNG格式的图片而不是JPG
- 使用尺寸更小的图片
- 使用WEBP格式的图片。可以在iOS和Android平台减少29%的二进制大小。
避免不必要的渲染
React Native是基于React的库并且处理组件渲染的形式类似于React.js。因此在React中可用的优化方法也适用于React Native。一个优化方法就是避免不必要的渲染,在函数组件中可以通过使用React.memo()
来完成。
React.memo
是被用来进行处理记忆化(memoization)。记忆化的理念是:如果一个组件接收相同的props超过一次,它将会使用之前一次缓存的props。并且函数组件只会进行一次渲染返回jsx
例如下面Parent组件和Child组件的例子。Parent组件有一个count的state变量,每次button点击的时候更新count
当button点击的时候,即使Child组件的props属性text没有改变,每次Parent组件渲染都会造成Child组件的重新渲染。Child组件没有做任何和Parent组件有关的操作而仅仅是展示一些静态文本。这个行为可以通过把Child组件用React.memo()
包着来进行优化
1 | // Parent.js |
Animated库中使用nativeDriver
React Native中有很多方法可以写动画,最常用的方法就是使用Animated库
Animated
Animated会在动画执行之前,通过nativeDriver把动画发送到原生bridge中,这有助于动画独立于被阻塞的JavaScript线程执行,动画会执行比较流畅而不会丢帧
通过设置useNativeDriver的值为true,可以在Animated库中使用nativeDriver。下面的例子就是在ScrollView组件的onScroll事件中使用useNativeDriver
1 | <ScrollView |
使用Flipper进行调试
React Native 0.62.0版本介绍了一个新的调试工具Flipper
。 这是一个给iOS、安卓和React Native使用的平台 。它直接集成在原生代码中,并且在React Native中开箱即用。
使用Flipper
调试app不需要远程调试。需要一个本地连接的Metro实例来与React Native应用进行交互。它可通过React DevTools来检查组件树并检查React组件的state和属性。
它使用原生插件生态系统来调试iOS和Android应用程序。这些插件可用于设备日志、崩溃报告、检查网络请求、检查应用程序的本地数据库、检查缓存的图像等。
使用Hermes
Hermes是一个专为移动端应用优化的开源javascript引擎。React Native 0.60.4版本之后,Hermes
在安卓也可用了。这有利于减少app的下载体积(安卓APK)、降低内存消耗和降低APP的可交互时间
在安卓APP中开启Hermes引擎,需要打开build.gradle
并且修改如下:
1 | def enableHermes = project.ext.react.get("enableHermes", true); |
自React Native 0.64-rc.0版本后,Hermes也能用于iOS平台。需要打开Podfile
并且修改如下:
1 | use_react_native!(:path => config[:reactNativePath], :hermes_enabled => true |
不要在源代码中保留console表达式
在Javascript应用包括React Native应用中,用console.log
调试是最常用的调试方法之一。然而,在构建React Native应用时,将console
语句留在源代码中可能对JavaScript线程造成一些瓶颈。
一个解决方法就是使用babel-plugin-transform-remove-console
删除掉console
语句。在终端通过下面的方法安装
1 | yarn add babel-plugin-transform-remove-console |
然后修改 .babelrc
文件如下来删除所有的console
语句
1 | { |
不要使用Scrollview渲染一个大列表数据
有一些方法可以在React Native中使用滚动列表。其中两种最常用的方式就是使用ScrollView
和FlatList
组件
ScrollView
用起来很简单,通常用于使用JavaScript的map()
函数遍历一个数组。 例如:
1 | <ScrollView> |
ScrollView
会一次性渲染所有的子组件,在需要渲染的子组件数量不多的时候会比较好用。但在处理大量的数据的时候会影响到APP的性能。
为了解决渲染大量数据的情况,React Native提供了一个FlatList
组件。这个组件能够懒加载子组件列表,这样APP就不会消耗大量的内存
例如:
1 | <FlatList |
结论
React Native是一个用于构建跨平台应用的开源框架。它以JavaScript为核心,并调用原生组件来构建移动端界面和功能。它会是一个高性能框架只要注意考虑到性能
- Post title:React Native性能优化:应该做和不应该做的
- Post author:flytam
- Create time:2021-03-03 19:37:57
- Post link:https://blog.flytam.vip/React Native性能优化:应该做和不应该做的.html
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.