Skip to content

渲染优化

引言

@autostorejs/react是一个基于Proxy的响应式状态系统,其提供了useReactivesignal机制来实现更细粒度的渲染。

以下我们就如何优化React渲染,举了几个例子。

Context

我们先看一个传统的Context的渲染例子。

从上面的例子可看到,当更新Context.age时,所有的子组件不管是否有使用Age均会重新渲染,而这是不必要的,因为子组件并没有使用到Context的数据,为此我们一般需要使用React.memo或一些第三方库来进行优化渲染。

提示

最大的问题在于,当更新根Context时,所有的子组件都会重新渲染,这是不必要的,因为子组件并没有使用到根Context的数据。我们希望能实现更细粒度的渲染,只有当子组件使用到的数据发生变化时,才会重新渲染。

useReactive

为了优化渲染逻辑,一般我们会使用React.memo来进行优化渲染。

  • 在上例中,当更新Age时,仅根组件会重新渲染,而FirstNameLastName不会重新渲染,因为它们并没有使用到Age
  • 当在根组件中更新FirstName时,仅FirstName会重新渲染。而LastName组件中没有FirstName,所以不会重新渲染。

提示

在大型React应用,面对复杂的状态变化,如何决定何时使用React.memo是一个很大的心智问题,也是最容易搞坑里的,这也是为什么React官方要推Compiler的原因

信号组件

而更好的办法就是最近比较流行的signal机制,signal机制可以将渲染颗粒度限定在组件范围,只有使用到数据的组件才会重新渲染。

基于Signal,渲染颗粒度可以是组件中的一个片段或ReactNode,更加精细,更加高效。

了解更多关于Signal的内容,可以阅读深入解析:React中的信号组件与细粒度更新

  • 在上例中,提供了更细粒度的更新,当状态变化时,仅$(....)内部会重新渲染,而其他部分不会重新渲染。再也不需要React.memo了。
  • 关于Signal的更多用法,可以参考信号组件

提示

本文档演示中使用的色块组件ColorBlock在最右侧会显示组件的渲染次数,每渲染一次+1,方便观察组件的渲染更新情况。