前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React 即将推出 Compiler,是时候告别 useMemo/useCallback 了!

React 即将推出 Compiler,是时候告别 useMemo/useCallback 了!

作者头像
ConardLi
发布2024-04-15 16:32:36
2670
发布2024-04-15 16:32:36
举报
文章被收录于专栏:code秘密花园

大家好,我是 ConardLi

最近,React 团队在他们的官方博客发表了一篇文章,介绍了从上个大版本发布,到 2024 年 2 月团队的一些工作内容。

其中最让我惊喜的就是 React Compiler 了。

众所周知,大家在介绍 React 的时候总会说它是一个重运行时的框架,因为它本身在编译时并不会做很多针对于渲染的优化动作。

这让开发者在开发阶段拥有了很多的灵活性,React 给我们提供了诸如 useMemo/useCallback 这样的 API ,把运行时优化的手段交给到了开发者手上。但这同样也给开发者带来了极大的心智负担,

虽然用好 React 可以让你的应用拥有极致的性能表现,但是事实上用好 React 远比我们想象中的要困难。

反观 Vue.js 这样的框架就不一样了,大家都说 Vue 相比 React 上手更简单,更适合初学者,主要就是因为它没有这么多的弯弯绕绕,很多优化事项能在编译时做就在编译时做了。

这次 React 推出 Compiler 可能要打破大家的这个常规认知了。

React 官方博客是这样描述它的:

当状态变化时,React 有时可能会过度渲染。自 React 问世以来,我们针对这类情况的解决方案一直是手动缓存。在我们当前的 API 中,这意味着应用 useMemouseCallbackmemo 这些 API,手动微调 React 在状态变更时的渲染范围。但是,手动缓存更像是一种妥协。它让我们的代码变得混乱,容易出错,而且需要额外的工作去保持最新。

手动缓存虽然是一个合理的妥协,但我们并不满意。我们更加希望的是,当状态变化时,React 自动渲染 UI 的正确部分,而无需妨碍 React 的核心思维模型。我们相信,React 的方法 —— UI 作为一个简单的状态函数,具有标准的 JavaScript 值和习惯用法 —— 是 React 对许多开发者来说易于上手的关键因素。这就是为何我们投资建造一个优化 React 的编译器。

React Compiler 现在并不是一个初步想法,它已经在 instagram.com 的生产环境中提供支持了。

在去年 React 团队的一场演讲中,已经对它进行了介绍,只不过当时它的名字叫做 React Forget ,目前更名为 React Compiler

React Compiler 基于 Babel 插件实现,它实际会做的事情,你可以简单这样理解:

它会把我们常见的 React 代码转换成每个钩子依赖、组件上的属性,以及组件本身都被缓存的代码,比如下面这段代码:

代码语言:javascript
复制
const Component = () => {
  const onSubmit = () => {};
  const onMount = () => {};

  useEffect(() => {
    onMount();
  }, [onMount]);

  return <Form onSubmit={onSubmit} />;
};

在底层,它的行为就相当于 onSubmitonMount 都被 useCallback 包裹上了,而 FormReact.memo 包裹上了:

代码语言:javascript
复制
const FormMemo = React.memo(Form);

const Component = () => {
  const onSubmit = useCallback(() => {}, []);
  const onMount = useCallback(() => {}, []);

  useEffect(() => {
    onMount();
  }, [onMount]);

  return <FormMemo onSubmit={onSubmit} />;
};

当然,Compiler 实际做的事情要比这个 Demo 要复杂的多。

想了解更详细的讲解,你可以看这个视频:https://www.youtube.com/watch?v=qOQClO3g8-Y

当前的版本中,如果一个父组件重新渲染,那么在其内部渲染的每个组件也会重新渲染。

代码语言:javascript
复制
// 如果 Parent 重新渲染
const Parent = () => {
  // Child 也会重新渲染
  return <Child />;
};

理想的状态是,只有当子组件的 props 改变时,子组件才会重新渲染。

使用 React Compiler 时,一切都在底层进行了缓存,这个理想状态就变成了事实。

在开发中,我们经常会使用一些性能优化的技巧,比如 "向下移动状态" 或 "将组件作为子组件传递",可以减少重新渲染。我通常建议在折腾 useCallbackmemo 之前先试试这些技巧,因为在 React 中正确地缓存状态非常难。

例如,在这段代码中:

代码语言:javascript
复制
const Component = () => {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setIsOpen(true)}>
        open dialog
      </Button>
      {isOpen && <ModalDialog />}
      <VerySlowComponent />
    </>
  );
};

每次打开对话框时,VerySlowComponent 都会重新渲染,导致对话框打开时有延迟。如果我们把打开对话框的状态封装在一个组件中,像这样:

代码语言:javascript
复制
const ButtonWithDialog = () => {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setIsOpen(true)}>
        open dialog
      </Button>
      {isOpen && <ModalDialog />}
    </>
  );
};

const Component = () => {
  return (
    <>
      <ButtonWithDialog />
      <VerySlowComponent />
    </>
  );
};

我们基本上摆脱了 VerySlowComponent 不必要的重新渲染,而不用缓存任何东西。

React Compiler 投入使用时,这些场景将不再对性能有任何影响,也不会再有任何重新渲染。

自然的,之前一直在困扰大家的 useMemouseCallback 将一去不复返了...

Andrew ClarkTwitter 上表示,React Compiler 预计在今年年底发布,另外 React 还会带来一些新的改变:

  • useMemouseCallbackmemo → React Compiler将自动处理和优化组件的重渲染和回调函数的生成,使这些函数将成为过去。
  • forwardRef → 引用(ref)将被视为一个普通的 props,你可以像处理其他 props 一样处理它,无需额外的 forwardRef 函数。
  • React.lazy → 用于代码分割的 React.lazy 也将被新的 RSC(React Server Component)和 promise-as-child 替代,这将对异步组件加载提供更好的支持。
  • useContext → 你只需使用 use(Context),就可以直接获取到 Context 的值,大大简化了 Context 的使用。
  • throw promise → 你可以直接使用 use(promise),让异步操作变得更加简单,无需再显式地去抛出和捕获 Promise。
  • <Context.Provider> → 你只需使用 <Context>,而不再需要 <Context.Provider>,这将使 Context 的提供者更容易使用和管理。

最后

大家觉得 React 即将发布的这些新特性怎么样?欢迎在评论区留言。

参考:

  • https://react.dev/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024
  • https://www.youtube.com/watch?v=qOQClO3g8-Y
  • https://twitter.com/acdlite/status/1758229889595977824
  • https://www.developerway.com/posts/react-compiler-soon

抖音前端架构团队目前放出不少新的 HC ,又看起会的小伙伴可以看看这篇文章:抖音前端架构团队正在寻找人才!FE/Client/Server/QA

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 code秘密花园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档