最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • [译] React Native性能优化:应该做和不应该做的|技术点评

    正文概述 掘金(flytam)   2021-03-04   754

    在使用一些框架例如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()包着来进行优化

    // 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>;
    });
    

    Animated库中使用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>
    

    使用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并且修改如下:

    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
    

    不要在源代码中保留console表达式

    在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"]
        }
      }
    }
    

    不要使用Scrollview渲染一个大列表数据

    有一些方法可以在React Native中使用滚动列表。其中两种最常用的方式就是使用ScrollViewFlatList组件

    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 春招闯关活动」, 点击查看 活动详情


    起源地下载网 » [译] React Native性能优化:应该做和不应该做的|技术点评

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元