• Meta 发布 React 编译器
  • 发布于 1周前
  • 48 热度
    0 评论
前言
React Conf 2024 上,React 社区引入了 React 编译器,这是一个前所未有的优化工具,能够提高 React 应用的性能。

正文从这开始~~

React 编译器是一个新的工具,它能够在不改变代码的情况下优化 React 应用的性能。该编译器能够识别组件的不同部分,并将它们转换为可被缓存的元素,从而在组件重新渲染时避免不必要的计算和渲染。例如,在一个简单的计数器应用中,编译器能够确保只有状态发生变化的组件才会重新渲染,而不是整个应用。这是通过将组件的 JSX 结构分解为可缓存的部分来实现的。

编译器的优化能力不仅限于简单的场景,它还能够处理更复杂的情况,比如嵌套组件和动态数据。在一个示例中,编译器能够将一个不变的常量直接嵌入到 JSX 中,而不是作为一个单独的变量存在,从而减少了渲染的复杂性。此外,React 编译器能够自动处理 useMemo 和 useCallback 的优化问题,使得开发者不再需要手动编写这些钩子函数来提高性能。

React 编译器的引入也带来了一些变化和挑战。例如,它目前还在开发中,不建议在生产环境中使用;它可能会与如 MobX 这样的状态管理库不兼容;它也可能会导致新的库和框架的出现,这些库和框架需要与编译器配合工作。尽管如此,React 编译器无疑为 React 应用的性能优化开辟了新的可能性,并可能改变未来的前端开发方式。

React 编译器使优化代码性能成为可能。Meta 使用该编译器已有一年多时间。

星期三,在拉斯维加斯举行的 React 会议(该会议通过网络直播)上,Meta 发布了一款开源的 React 编译器。Meta React 团队成员、用户界面工程师乔・萨沃纳(Joe Savona)表示,该团队在过去几年中一直在开发这款编译器。React 编译器会自动优化你的组件和钩子,这样一来,只有 UI 中与状态变化相关的最小部分会更新,” 萨沃纳对听众说。“这看起来真是太神奇了。

为什么需要 React 编译器?
为什么解释型语言需要编译器?萨沃纳将 React Compiler 与 Meta 的 Hermes 和 V8 联盟的 V8 进行了比较,这些是包含编译器的 JavaScript 引擎。他说:"React Compiler 更像是 TypeScript,或者是 JavaScript 引擎内部的编译器,比如 V8 或 Hermes。" 它会将代码分解为单个表达式,并构建控制流和数据流图。它可以执行复杂的优化操作,如消除无用代码、常量传播、类型推断,甚至还有别名分析以及其他许多优化操作。”

他补充说,这些优化通常会出现在 JavaScript 引擎或 Rust 或 C++ 等语言的编译器中。他继续说,React 编译器将这些理念应用到 JavaScript 中,在不影响开发者体验的情况下提高了性能。他表示,代码没有改变,但应用程序和更新默认会变得更快。

萨沃纳补充说:" 实际上,我们的代码甚至会变得更加简洁明了,因为我们不需要手动实现缓存。缓存是一种优化技术。”

将代码应用于 React 编译器
他指向早些时候用 React 构建的媒体播放器演示。他说,这个媒体播放器没有使用 memo 调用,也没有随机和不必要的回调函数,但是代码中包含了开发者可能不会总是考虑到的很多信息。

他说:” 例如,考虑一下过滤后的歌曲列表 "。React 显然需要再次过滤歌曲列表并更新播放列表。这段代码还告诉我们逆向关系;如果歌曲没有发生变化,那么 React 就不需要更新过滤后的歌曲,也不需要更新播放列表。

他补充说:“当歌曲没有改变时,没有必要更新播放列表。这就是启用编译器后发生的情况。”

“这是因为 JavaScript 和 React 对于它们的工作方式有明确的规则,我们已经学会了这些规则。我们在阅读代码、编写代码、调试代码和偶尔测试代码时每天都会使用它们。”

他补充说,编译器可以被教会理解这些规则。然后它就可以 “像我们一样” 看到代码,“只是更加彻底而已”。他表示,该技术可以将这一过程应用于代码中的每一个值,从而创建出数据在用户界面中移动的计算图。

编译器了解 React 的规则,并且知道一些额外的信息。"例如,它知道设置状态函数实际上不会改变,因此编译器无需考虑该值是否会更新。因此,我们可以移除这种依赖关系"。那么唯一需要更新的只是当前播放的歌曲,而不是整个播放列表。

他表示:" 最好的部分是,所有这些信息都来自你今天正在编写的 React 组件和钩子 “。“不需要学习新的 API。不需要改变你编写代码的方式。我们只需要利用你当前代码中已经存在的所有信息。”他补充说,这类精确的 UI 更新有时被称为细粒度响应性。

接下来,Meta 软件工程师 @Mofei Zhang 上台展示了该编译器在 Meta 应用中的运行情况。在具有大量交互性或组件的页面上,Meta 发现开发者开始进行权衡取舍。

我们看到的一小部分代码非常难以阅读,"Zhang 说。“这部分代码包含了许多手动优化,有助于让 UI 感觉更流畅,但也让代码更难理解。”她展示了一个代码片段,其中有近 20 处开发人员对对象进行了手工优化。

Meta 在 Instagram 和 Quest 上试用 React 编译器
2023 年,Meta 开始在 Instagram.com 和 Quest 商店(Meta Quest VR 设备的应用商店)这两个应用上推出 React Compiler。她说,经过编译器优化的版本比以前快了两倍多。初始加载时间和跨页面导航时间提高了 12%。而且对内存使用和整体崩溃(可能反映内存不足错误)都没有影响。Quest 的导航加载速度至少快了 4%。Instagram 在每个路径上的平均速度提高了 3%。

在 Meta,这确实是件大事,"Zhang 说。“为了说明这些数字,工程师们对这些应用程序的每一个字节都进行了检查,并添加了数千个缓存调用。”她补充说,对于特定页面的某些指标,只要在首次绘制等指标上提高 1 或 2 个百分点,就会产生巨大的影响。她说:"React Compiler 显著提高了每个页面的性能。" 在优化程度较低的应用程序上,我们发现 React Compiler 可以增加超过源代码中已有 memoization 的 15 倍。

她总结说,使用编译器可以让开发者在没有手动优化的应用程序上获得快速的交互,同时提高已优化应用程序的可读性和可维护性。开发者甚至可以移除手动编写的缓存代码。

她说:" 我们刚刚看到 React Compiler 是如何提高应用程序的速度上限的,因为它可以优化的不仅仅是开发者通过嵌套和条件缓存以及复杂的静态分析所能实现的。“我们继续将该编译器应用于更多的应用程序,以对其进行迭代优化。”

除了开放源代码外,还有 React 编译器的实验场供想要探索其工作原理的开发者使用。

萨沃纳上台作总结发言。
他说:"React Compiler 允许开发者继续编写他们熟悉的代码。" 事实上,正如我们所看到的,我们不再需要手动实现缓存。……React Compiler 可以为实际应用带来显著的性能提升。”
用户评论