Meta的React Compiler 1.0将自动记忆化引入到生产环境
来源: InfoQ 话题 - 大前端
React是一个被广泛采用的用于构建用户界面的JavaScript库,随着React Compiler 1.0的稳定发布,React达到了一个里程碑,这个版本建立在近十年的工程工作和编译器学习的基础之上,改变了开发人员优化React应用程序的方式。
React Compiler 1.0是一个构建时工具,通过自动记忆化来优化React应用程序,同时支持React和React Native,而无需重写代码。该编译器已经在Meta的主要应用程序中经过了实战测试,现在完全准备好投入生产。该工具分析组件数据流和可变性,以消除不必要的渲染,覆盖手动 useMemo 和 useCallback 实现无法处理的条件路径。
编译器通过 eslint-plugin-react-hooks 中的推荐预设集成了诊断功能,同时为Expo、Vite和Next.js提供了第一方模板。Expo SDK 54默认启用了编译器,而Vite和Next.js为新应用程序提供了启用编译器的启动器。Next.js 16将React Compiler支持列为稳定的,团队建议在启用编译器时使用15.3.1或更高版本的Next.js。
在生产环境中,性能得到了显著的。Meta报告称,初始加载速度提高了高达12%,在Meta Quest Store中的交互速度提高了2.5倍以上,尽管结果因应用程序而异。来自Sanity Studio和Wakelet的真实案例研究展示了采用编译器后可衡量的性能提升,开发者报告组件渲染效率有了明显的改善。
额外的真实度量指标提供了编译器影响的详细见解。Sanity Studio在他们的2024年11月变更日志中记录了使用React Compiler预编译他们的包后的重大收益:
到目前为止,已经编译了1411个组件中的1231个,从而使渲染时间和延迟减少了20%到30%。。当我们重构剩下的180个组件以支持自动记忆时,我们预计会有更大的改进。
Wakelet在他们的案例研究中分享了将编译器推向100%用户后的综合生产指标:
总体而言,我们的LCP提高了10%(从2.6秒提高到2.4秒),我们的INP提高了约15%(从275毫秒降到240毫秒)。通过更细粒度的测试,我们发现在纯React元素(如Radix下拉菜单)中获得的收益最大,其中INP加速接近30%。
独立开发者Nadia Makarevich在一个大约有15,000行代码的真实应用程序上进行了测试,结果参差不齐。初始加载性能的影响很小,启用编译器之前和之后的Lighthouse分数几乎保持一致。然而,交互性能的提升因用例而异。在一个测量主题切换交互的测试中,总阻塞时间从280毫秒降至零。在另一个涉及复选框筛选交互的测试中,阻塞时间从130毫秒减少到90毫秒,尽管编译器未能消除由于来自外部库的非记忆对象引用而导致的所有重新渲染。
编译器的开发历史可以追溯到React团队在2017年对编译器的首次探索,即Prepack。尽管该项目最终被终止,但所学到的知识为Hooks的设计提供了信息,Hooks是为未来编译器而创建的。在2021年,当前编译器方法的第一次迭代被演示,导致可在React Conf 2024上发布的实验版本和随后发布的全年beta版本。
与流行库的兼容性问题仍然存在。GitHub讨论显示,react-hook-form用户报告某些函数,包括useWatch和getValues,在编译器下可能会遇到问题。
React团队通过一个可选的react-compiler-runtime包,正式支持React 17及更高版本的应用程序上的编译器,使团队可以逐步采用,而不是升级到React 19。鼓励当前使用早期版本的开发者使用react-compiler-healthcheck工具检查兼容性,并查看与1.0版本一起发布的逐步采用指南。迁移文档建议从React 18.3开始,该版本包括对React 19兼容性所需的弃用API的警告。
React Compiler为现有的React生态系统带来了优化,而无需更改框架,它将这种能力添加到React的以运行时为中心的体系结构中。编译器代表了React性能优化哲学的转变,从手动开发者干预转向自动化构建时分析,尽管团队建议在效果依赖项需要精确控制的地方保留 useMemo 和 useCallback 作为应急出口。
原文链接: