稀土掘金技术社区 11月04日 09:47
React Compiler 1.0 发布:四年等待,告别手动优化
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

React 团队在 2021 年首次展示的 React Forget 项目,如今已发展为 babel-plugin-react-compiler 1.0 稳定版。这一重大更新标志着 React 在性能优化方面迈入了自动化时代,开发者无需再手动编写大量的 `memo`、`useCallback` 和 `useMemo` 来避免不必要的组件重渲染。文章回顾了 React 在性能优化上的挑战,对比了 Vue 的细粒度响应式更新机制,并详细介绍了 React Compiler 如何通过静态分析在编译阶段自动进行优化,以及 React 19.2 新特性带来的便利,如 `Activity` 和 `useEffectEvent`,解决了困扰开发者已久的 KeepAlive 问题,让开发体验大幅提升。

🧰 **React Compiler 自动化性能优化**:React Compiler(前身为 React Forget)已发布 1.0 稳定版,它通过编译时静态分析,自动为组件添加必要的性能优化,开发者无需手动介入 `React.memo`、`useCallback` 和 `useMemo`,显著减少了“屎山”代码,提升了开发效率和代码可读性。

💡 **解决 React 性能痛点**:文章对比了 React 在状态更新时可能导致的大量不必要重渲染的问题,以及开发者为解决此问题而不得不手动添加的优化代码。通过引入 React Compiler,React 终于能像 Vue 一样实现更优雅、自动化的细粒度更新,解决了开发者长期以来的性能优化难题。

🚀 **React 19.2 新特性与 KeepAlive 优化**:React 19.2 的更新带来了 `Activity` 和 `useEffectEvent` 等新特性,解决了过去实现组件状态保持(KeepAlive)的复杂性。此前,开发者需要借助 Suspense 或手动管理组件卸载等方式来模拟 KeepAlive,代码复杂且易出错。新特性让这一功能变得更加简洁和健壮。

🌟 **四年等待的价值**:从 2021 年 React Conf 首次亮相到如今 1.0 稳定版的发布,React Compiler 的出现标志着 React 在性能优化方面取得了重大突破。尽管过程漫长,但其带来的自动化优化能力、简化的开发流程以及更佳的开发体验,证明了这四年的等待是值得的,React 正在为开发者提供更高效、便捷的开发工具。

原创 寅时码 2025-11-04 08:30 重庆

还记得 2021 年 React Conf 上,React 团队首次展示了那个让人眼前一亮的项目——「React Forget」。当时我就想,终于!React 终于要解决那个让人头疼的性能问题了。

点击关注公众号,“技术干货” 及时达!

好事连连React 脱离 Facebook,成立基金会(以前 React 被 Vercel Nestjs 夺舍,更新的都是无用功能,对于开发体验毫无提升)

React 19.2 更新 「Activity、useEffectEvent」 等新特性。终于不用手动封装 「KeepAlive」 了

React Compiler 发布 1.0 稳定版,「告别手动 Memo」

好事连连啊

那些年被 React 折磨的日子从 React Forget 到 babel-plugin-react-compiler,这四年的等待终于有了结果

还记得 2021 年 React Conf 上,React 团队首次展示了那个让人眼前一亮的项目——「React Forget」。当时我就想,终于!React 终于要解决那个让人头疼的性能问题了。

四年过去了,从 React Forget 到现在的 babel-plugin-react-compiler 1.0,这四年的等待让我深刻体会到了什么叫 "望眼欲穿"。

React 的 "愚蠢":为什么我们需要手动优化?那些年我们写过的 "屎山" 代码在 React 的世界里,性能优化一直是个让人头疼的问题。每次组件的 state 或 props 发生变化,React 都会从根节点开始对比,判断哪些节点需要更新。这种机制导致了大量不必要的重新渲染。

为了避免这些不必要的渲染,我们不得不在代码里写满这样的 「memo」 "屎山":

    const ExpensiveComponent = React.memo(({ data, onUpdate }) => {
      const processedData = useMemo(() => {
        return data.map(item => ({
          ...item,
          processedexpensiveCalculation(item)
        }))
      }, [data])

      const handleClick = useCallback(() => {
        onUpdate(processedData)
      }, [processedData, onUpdate])

      return (
        <div onClick={handleClick}>
          {processedData.map(item => (
            <Item key={item.id} data={item} />
          ))}
        </div>
      )
    })

    Vue 的 "优雅":细粒度响应式更新再看看 Vue,人家是怎么做的:

      <template>
        <div @click="handleClick">
          <Item 
            v-for="item in processedData" 
            :key="item.id" 
            :data="item" 
          />
        </div>
      </template>

      <script setup>
      const processedData = computed(() => {
        return data.value.map(item => ({
          ...item,
          processedexpensiveCalculation(item)
        }))
      })

      const handleClick = () => {
        onUpdate(processedData.value)
      }
      </script>

      简洁、优雅、自动优化。Vue 的细粒度响应式更新机制能够自动追踪数据的变化,并仅更新受影响的组件。开发者无需手动进行复杂的优化操作,代码更加直观和高效。

      React Compiler:四年的等待终于有了结果从React Forget到babel-plugin-react-compiler2021 年,React 团队在 React Conf 上首次展示了 React Forget 项目。这个项目的目标很明确:通过编译器自动优化组件的渲染性能,让开发者无需手动添加 React.memouseCallback 和 useMemo 等优化代码。

      经过四年的打磨,这项技术终于以 babel-plugin-react-compiler 的形式与开发者见面,现已发布稳定版 1.0

      react.dev/learn/react…[1]

      www.npmjs.com/package/bab…[2]

      自动化的性能优化React Compiler 通过静态分析代码,在编译阶段自动为组件添加必要的优化:

      这是我写的源代码

        import { useState } from 'react'

        export default function App() {
          const [count, setCount] = useState(0)

          return (
            <div className='h-screen w-screen flex justify-center items-center flex-col gap-8'>
              <Comp1 />
              <button onClick={ () => setCount(count + 1) }>+</button>
              <button onClick={ () => setCount(count - 1) }>-</button>
              <p>{ count }</p>
              <Comp2 />
            </div>
          )
        }

        function Comp1() {
          return <div class>Comp1 { Math.random() }</div>
        }

        function Comp2() {
          return <div class>Comp2 { Math.random() }</div>
        }

        接下来配置一下 Vite,看看编译产物,先关闭代码混淆压缩

        在开启 「React Compiler」 打包后的结果如下

        关闭 「React Compiler」 打包后的结果如下

        就这么简单!无需修改任何业务代码,编译器会自动处理所有的性能优化。

        没有 React 19.2 以前,需要自己解决 KeepAlive 问题过去实现组件状态保持(KeepAlive)是个老大难问题

        很多人可以认为 display: none 能解决一切,那只能说明的开发经验太浅了

        display: none 的局限」

        组件仍会渲染和初始化

        获取不到正确的 DOM 尺寸

        会触发生命周期和副作用

        多个隐藏组件会造成性能浪费

        以前我是自己封装 KeepAlive 组件,需要借助 Suspense 挂起渲染,或手动管理组件卸载,代码复杂且容易出问题,代码大致思路如下

          import type { KeepAliveProps } from './type'
          import { memo, Suspense, use } from 'react'
          import { KeepAliveContext } from './context'

          const Wrapper = memo<KeepAliveProps>(({ children, active }) => {
            const resolveRef = useRef<Function | null>(null)

            if (active) {
              resolveRef.current?.()
              resolveRef.current = null
            }
            else {
              throw new Promise((resolve) => {
                resolveRef.current = resolve
              })
            }

            return children
          })

          /**
           * 利用 Suspense 实现的 KeepAlive 组件
           * 当 active 为 false 时,抛异常,触发 Suspense 的 fallback
           * 当 active 为 true 时,resolve 异常,触发 Suspense 的正常渲染
           */
          export const KeepAlive = memo(({
            uniqueKey: key,
            active,
            children,
          }: KeepAliveProps & { uniqueKey?: keyof any }) => {
            const { findEffect } = use(KeepAliveContext)
            /**
             * 触发钩子
             */
            useEffect(() => {
              const { activeEffect, deactiveEffect } = findEffect(key)

              if (active) {
                activeEffect.forEach(fn => fn())
              }
              else {
                deactiveEffect.forEach(fn => fn())
              }
            }, [active, findEffect, key])

            return <Suspense fallback={ null }>
              <Wrapper active={ active }>
                { children }
              </Wrapper>
            </Suspense>
          })

          好起来了四年的等待,从 React Forget 到 babel-plugin-react-compiler,React 终于迎来了自动化的性能优化时代。并且还带来了 React 19.2 各项好特性,终于不是 「SHIT SSR」 了

          虽然 React 在性能优化方面曾经被诟病,虽然我们曾经写过无数的 "屎山" 代码,虽然 Vue 等框架在响应式更新方面确实更加优雅,但 React Compiler 的到来无疑为 React 开发者带来了福音。

          它通过自动化的性能优化,简化了开发流程,降低了出错的风险。开发者可以专注于业务逻辑,而无需担心性能优化的细节。

          四年的等待值得吗?我想说,值得。因为这意味着 React 正在迎头赶上,为开发者提供更高效、更便捷的开发体验。

          ""~

          阅读原文

          跳转微信打开

          Fish AI Reader

          Fish AI Reader

          AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

          FishAI

          FishAI

          鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

          联系邮箱 441953276@qq.com

          相关标签

          React Compiler React Forget 性能优化 JavaScript 前端 React 19.2 KeepAlive React.memo useCallback useMemo babel-plugin-react-compiler
          相关文章