React Native 渲染优化的一些经验分享

React Native 的性能应该一直是大家关心的重点,我们也会经常说到 React Native 应用的主要优势在于性能比较好,但其背后的主要原因之一得归功于其高效的渲染能力。

除了上一篇文章:juejin.cn/post/729565... 分析到的我们可以在应用打开阶段通过 JavaScript Engine 的方式优化应用页面打开阶段遇到的白屏和加载时间过长的问题,我们也可以在 React Native 应用运行过程中进行优化。

而在应用运行过程中渲染是非常重要的一部分,运行时会分别创建三个线程:JS Thread、Shadow Thread、Main Thread,在这三个线程中分别会创建三棵树,JS线程中会创建 Fiber Tree,在Shadow 线程中会创建 Shadow Tree,在UI线程中会创建 View Tree。

首先在 React Native 应用中需要在构建 fiber 对象,其次通过桥的方式通知 UI Manage 构建一颗 Shadow Tree,最后 Native 根据 Shadow Tree 映射成 Native 元素并渲染。

所以至少从流程上面来看,整个渲染是相对复杂和繁琐的,那应该如何去做好渲染缓解的优化工作呢?

渲染优化的办法

更多时候在渲染上的优化都是在 React render 阶段进行,其中可以实施的方法有好几种,这里主要介绍4种我个人认为比较常用到的方式:

1、使用 PureComponent

首先需要说明下,PureComponent 是一种特殊的组件,它会在其 props 或 state 发生变化时进行浅比较。如果 props 或 state 没有发生变化,则 PureComponent 不会重新渲染。这可以大大提高渲染性能,尤其是当组件的 props 或 state 经常发生变化时。

scala 复制代码
import React from "react"
import { View, TouchableOpacity, Text } from "react-native"

class Children extends React.PureComponent{
  //...
}

2、使用 shouldComponentUpdate

在有的时候,我们单纯把控制渲染性能调优交给 React 组件本身处理显然是靠不住的,React 需要提供给使用者一种更灵活配置的自定义渲染方案,使用者可以自己决定是否更新当前组件,shouldComponentUpdate 就能达到这种效果。

shouldComponentUpdate 是一种生命周期方法,它会在组件的 props 或 state 发生变化时被调用。如果 shouldComponentUpdate 返回 false,则组件不会重新渲染。这可以大大提高渲染性能,尤其是当组件的 props 或 state 经常发生变化时。

要使用 shouldComponentUpdate,只需在组件中定义该方法即可。这里举一个例子:

scala 复制代码
class MyComponent extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    // ...
    return true;
  }

  // ...
}

3、使用 React.memo

React.memo 是一种函数,可作为一种容器化的控制渲染方案,它可以将一个组件包装成一个新的组件,该组件会在其 props 或 state 发生变化时进行浅比较。如果 props 或 state 没有发生变化,则新组件不会重新渲染。这可以大大提高渲染性能,尤其是当组件的 props 或 state 经常发生变化时。

要使用 memo,只需将其作为组件的包装函数即可。例如:

javascript 复制代码
const MyComponent = memo(function MyComponent(props) {
  // ...
});

4、缓存React.element对象

React.element 是一种父对子的渲染控制方案,缓存了 element 对象。这里我们可以先看看这里一个示例:

javascript 复制代码
import React from "react"
import { View, TouchableOpacity, Text } from "react-native"

function Children () {
  return <View>子组件</View>
}

function App(){
  const [ number, setNumber ] = React.useState(0)
  /* 这里把 Children 组件对应的 element 元素缓存起来了 */
  const children = React.useMemo(()=><Children />,[])
  const onPress = () => setNumber(number => number + 1);
  return <View >
    父组件
    <TouchableOpacity onPress={onPress} >
    <View>
    <Text>add</Text>
    </View>
    </TouchableOpacity>
    </View>
}

当然在渲染环节还有其他的方法,例如 StyleSheet 、useCallback、Animated 库等,都能在一定程度上提高应用的性能,并使其更流畅。

相关推荐
哆啦A梦15881 小时前
[前台小程序] 01 项目初始化
前端·vue.js·uni-app
小周同学@3 小时前
谈谈对this的理解
开发语言·前端·javascript
Wiktok3 小时前
Pyside6加载本地html文件并实现与Javascript进行通信
前端·javascript·html·pyside6
一只小风华~3 小时前
Vue:条件渲染 (Conditional Rendering)
前端·javascript·vue.js·typescript·前端框架
柯南二号3 小时前
【大前端】前端生成二维码
前端·二维码
程序员码歌4 小时前
明年35岁了,如何破局?说说心里话
android·前端·后端
博客zhu虎康5 小时前
React Hooks 报错?一招解决useState问题
前端·javascript·react.js
灰海5 小时前
vue中通过heatmap.js实现热力图(多个热力点)热区展示(带鼠标移入弹窗)
前端·javascript·vue.js·heatmap·heatmapjs
王源骏5 小时前
LayaAir鼠标(手指)控制相机旋转,限制角度
前端
大虾写代码6 小时前
vue3+TS项目配置Eslint+prettier+husky语法校验
前端·vue·eslint