随笔

React Compiler

上个月 React Conf 推出了 React 19 RC,意味着其中有一个重磅级功能 - React Compiler 可以使用了,之前简单看了下大概,这次上手实验下。

Optimize

The initial release of React Compiler is primarily focused on improving update performance (re-rendering existing components).

开篇就点明了最初版本专注于提高更新的性能,也就是 re-render 组件的性能,其中有两个点:

Skipping cascading re-rendering of components

众所周知,只要一个组件触发了更新,那么它的子级除非使用 useMemo(), useCallback(), React.memo() 等手段优化外,一律会被动 re-render。

之前的推荐做法是,正常写就当不存在,当出现性能问题时再加优化手段,因为这些优化手段也会造成一定的逻辑复杂度和代码冗余,带来了很多心智负担。

右边是一个经过 React Compiler 处理过的代码,可以看到$[0] === Symbol这一段就是在判断是否有缓存,有就用没有就保存起来下次 re-render 的时候再用。
basic.png

第二个例子包含了状态变量,根据消费不同判断逻辑也不同,访问属性,会去判断属性是否一致,而不只是简单的统一判断对象是否发生了改变。
state.png

Skipping cascading re-rendering of components

跳过昂贵的计算,指的是在组件中写了一些逻辑处理函数,对数据进行二次处理,如果计算很复杂或者数据很大,可能就比较耗时,尤其是在组件会 re-render 且数据无变更的情况下,就会很费性能,一般都会手动用 useMemo 再包装下。

remove-useMemo.png

注意图片中的 if 判断,$[0] !== items 判断了这个普通的外部函数的入参,当参数不一致时,才会重新调用计算。

很熟悉是不是?没错,这就是 useMemo 的功能,而且是自动收集依赖的版本。

你也可能会想,这样以来所有的地方都需要进行一次判断,会不会反而更耗费性能呢?目前看来的情况是不太会,首先它是用的全等判断,其次根据网友跑的测试,百万级对比才到毫秒,而一次更新的量级一般其实也就几千最多了。

现在就用

https://19.react.dev/learn/react-compiler#getting-started

首先需要安装一个插件,比如 Vite 需要装 babel-plugin-react-compiler,然后配置需要使用的目录,此处直接配置为 src 目录下。

export default defineConfig({
  plugins: [react({
    babel: {
      plugins: [
        ["babel-plugin-react-compiler", {
          sources: (filename: string) => {
            return filename.indexOf('src') !== -1;
          },
        }],
      ],
    },
  })],
})

然后,就可以开始使用啦!

本文链接:https://note.lilonghe.net/post/react-compiler.html

-- EOF --