React 编译器
🤖 作者简介:水煮白菜王,一位前端劝退师 👻
👀 文章专栏: 前端专栏 ,记录一下平时在博客写作中,总结出的一些开发技巧和知识归纳总结✍。
感谢支持💕💕💕
本文内容参考自 React文档 - React Compiler 内容进行记录和整理✍
目录
- React 编译器
- 编译器是做什么的?
- 注意
- 深入探究
- React Compiler 添加了什么样的记忆?
- 优化重新渲染
- 昂贵的计算也会被记忆化
- 开始使用
- 安装 eslint-plugin-react-hooks
- 将编译器推出到您的代码库
- 现有项目
- 新项目
- 在 React 17 或 18 中使用 React 编译器
- 在库上使用编译器
- 用法
- Babel
- Vite
- Next.js :
- Remix
- Webpack
- 故障 排除
- 编译器假定什么?
- 如何知道我的组件已优化?
- 编译后某些内容无法正常工作
- 如果你觉得这篇文章对你有帮助,请点赞 👍、收藏 👏 并关注我!👀
React 编译器
本文将为你介绍 React Compiler 以及如何成功试用它
本文您进入React 编译器将学习
编译器入门
安装编译器和 ESLint 插件
进行故障排除
注意
React Compiler 是目前在 RC 中的一个新编译器,React已经开源了它以从社区获得反馈。现在建议大家试用编译器并提供反馈。
最新的 RC 版本可以通过标签找到,每日实验版本可以使用.@rc@experimental
React Compiler 是React开源的一个新的编译器,用于从社区获取反馈。它是一个仅限构建时的工具,可自动优化您的 React 应用程序。它与纯 JavaScript 一起工作,并且理解 React 的规则,因此你不需要重写任何代码来使用它。
eslint-plugin-react-hooks 还包括一个 ESLint 规则,该规则直接在编辑器中显示来自编译器的分析。React强烈建议大家立即使用 Linter。Linter 不需要您安装编译器,因此即使您还没有准备好试用编译器,也可以使用它。
该编译器目前作为 发布,可以在 React 17+ 应用程序和库上试用。要安装 RC:rc
npm
npm install -D babel-plugin-react-compiler@rc eslint-plugin-react-hooks@^6.0.0-rc.1
yarn
yarn add -D babel-plugin-react-compiler@rc eslint-plugin-react-hooks@^6.0.0-rc.1
编译器是做什么的?
为了优化应用程序,React Compiler 会自动记住你的代码。您现在可能熟悉通过 API 进行记忆化,例如 、 和 。通过这些 API,你可以告诉 React 如果它们的输入没有改变,你的应用程序的某些部分就不需要重新计算,从而减少了更新的工作。虽然功能强大,但很容易忘记应用记忆化或错误地应用它们。这可能会导致更新效率低下,因为 React 必须检查没有任何有意义的更改的 UI 部分。useMemouseCallbackReact.memo
编译器利用其 JavaScript 和 React 规则的知识来自动记住组件和 hook 中的值或值组。如果它检测到规则的破坏,它将自动跳过这些组件或 hook,并继续安全地编译其他代码。
注意
React Compiler 可以静态检测何时违反 React 规则,并安全地选择退出仅优化受影响的组件或钩子。编译器没有必要优化 100% 的代码库
如果您的代码库已经很好地记住了,您可能不希望看到编译器的性能有重大改进。但是,在实践中,记住导致性能问题的正确依赖项是很棘手的。
深入探究
React Compiler 添加了什么样的记忆?
React Compiler 的初始版本主要专注于提高更新性能(重新渲染现有组件),因此它专注于以下两个用例:
1.跳过组件的级联重新渲染
- 重新渲染会导致其组件树中的许多组件重新渲染,即使只有更改
<Parent /><Parent />
2.跳过 React 外部的昂贵计算
- 例如,在需要该数据的组件或 hook 内部调用
expensivelyProcessAReallyLargeArrayOfObjects()
优化重新渲染
React 允许你将你的 UI 表示为当前状态的函数(更具体地说:它们的 props、state 和 context)。在当前的实现中,当组件的状态发生变化时,React 将重新渲染该组件及其所有子组件 — 除非你使用 、 或 应用了某种形式的手动记忆。例如,在下面的示例中,每当 的状态发生变化时,都会重新渲染:
useMemo()
useCallback()
React.memo() <MessageButton><FriendList>
function FriendList({ friends }) {const onlineCount = useFriendOnlineCount(); if (friends.length === 0) {return <NoFriends />;}return (<div><span>{onlineCount} online</span>{friends.map((friend) => (<FriendListCard key={friend.id} friend={friend} />))}<MessageButton /></div>); }
React Compiler 会自动应用等同于手动记忆化的作,确保只有应用程序的相关部分会随着状态变化而重新渲染,这有时被称为“细粒度响应性”。在上面的例子中,React 编译器确定 of 的返回值即使作为更改也可以重用,并且可以避免重新创建这个 JSX,并避免在 count 发生变化时重新渲染。
<FriendListCard />friends<MessageButton>
昂贵的计算也会被记忆化
编译器还可以自动 memoize 渲染期间使用的昂贵计算:
// **Not** memoized by React Compiler, since this is not a component or hook function expensivelyProcessAReallyLargeArrayOfObjects() { /* ... */ }// Memoized by React Compiler since this is a component function TableContainer({ items }) {// This function call would be memoized:const data = expensivelyProcessAReallyLargeArrayOfObjects(items);// ... }
但是,如果确实是一个昂贵的函数,你可能需要考虑在 React 之外实现自己的记忆化,因为:
expensivelyProcessAReallyLargeArrayOfObjects
- React 编译器只记住 React 组件和钩子,而不是每个函数
- React Compiler 的记忆不会在多个组件或 hook 之间共享
因此,如果用于许多不同的组件,即使传递了完全相同的项目,也会重复运行昂贵的计算。建议先进行分析,看看它是否真的那么昂贵,然后再使代码变得更复杂。
expensivelyProcessAReallyLargeArrayOfObjects
开始使用
安装 eslint-plugin-react-hooks
React Compiler 还为 ESLint 插件提供支持。你可以通过安装 eslint-plugin-react-hooks@^6.0.0-rc.1 来试用。
npm install -D eslint-plugin-react-hooks@^6.0.0-rc.1
ESLint 插件将在编辑器中显示任何违反 React 规则的行为。当它这样做时,这意味着编译器跳过了优化该组件或 hook。这是完全可以的,编译器可以恢复并继续优化代码库中的其他组件。
你不必立即修复所有 ESLint 冲突。您可以按照自己的节奏解决它们,以增加要优化的组件和 hook 的数量,但不需要在使用编译器之前修复所有问题。
将编译器推出到您的代码库
现有项目
编译器旨在编译遵循 React 规则的功能组件和 hook。它还可以通过救助 (跳过) 这些组件或 hook 来处理违反这些规则的代码。然而,由于 JavaScript 的灵活性,编译器无法捕获所有可能的违规,并且可能会以漏报进行编译:也就是说,编译器可能会意外编译一个违反 React 规则的组件/钩子,这可能导致未定义的行为。
因此,要在现有项目中成功采用编译器,建议先在产品代码中的小目录上运行它。您可以通过将编译器配置为仅在一组特定的目录上运行来执行此作:
const ReactCompilerConfig = {sources: (filename) => {return filename.indexOf('src/path/to/dir') !== -1;},
};
您对推出编译器更有信心时,您也可以将覆盖范围扩展到其他目录,并慢慢将其扩展到整个应用程序。
新项目
如果要启动新项目,则可以在整个代码库上启用编译器,这是默认行为。
在 React 17 或 18 中使用 React 编译器
React 编译器与 React 19 RC 配合得最好。如果您无法升级,您可以安装额外的软件包,这将允许编译后的代码在 19 之前的版本上运行。但是,请注意,支持的最低版本为 17。react-compiler-runtime
npm install react-compiler-runtime@rc
你还应该将 correct 添加到你的编译器配置中,其中 是你目标的 React 的主要版本:target target
// babel.config.js
const ReactCompilerConfig = {target: '18' // '17' | '18' | '19'
};module.exports = function () {return {plugins: [['babel-plugin-react-compiler', ReactCompilerConfig],],};
}
在库上使用编译器
React Compiler 也可以用于编译库。因为 React Compiler 需要在任何代码转换之前在原始源代码上运行,所以应用程序的构建管道不可能编译它们使用的库。因此,建议库维护者使用编译器独立编译和测试他们的库,并将编译后的代码发送到 npm。
由于您的代码是预编译的,因此您的库的用户不需要启用编译器即可从应用于您的库的自动记忆化中受益。如果你的库面向尚未在 React 19 上运行的应用程序,请指定最小目标并将 react-compiler-runtime
添加为直接依赖项。运行时包将根据应用程序的版本使用正确的 API 实现,并在必要时对缺少的 API 进行 polyfill 填充。
库代码通常需要更复杂的模式和转义舱口的使用。因此,建议您确保进行足够的测试,以便识别在库上使用编译器可能出现的任何问题。如果你发现任何问题,你可以随时使用 'use no memo' 指令
选择退出特定的组件或 hook。
与 app 类似,你不需要完全编译 100% 的组件或 hook 就能看到你的库里的好处。一个好的起点可能是确定库中对性能最敏感的部分,并确保它们不会违反 React 规则,你可以用它来识别。eslint-plugin-react-compiler
用法
Babel
npm install babel-plugin-react-compiler@rc
编译器包括一个 Babel 插件,您可以在构建管道中使用它来运行编译器。
安装后,将其添加到你的 Babel 配置中。请注意,编译器首先在管道中运行至关重要:
// babel.config.js
const ReactCompilerConfig = { /* ... */ };module.exports = function () {return {plugins: [['babel-plugin-react-compiler', ReactCompilerConfig], // must run first!// ...],};
};
babel-plugin-react-compiler
应该在其他 Babel 插件之前先运行,因为编译器需要输入源信息进行声音分析。
Vite
如果你使用 Vite,你可以将插件添加到 vite-plugin-react 中:
// vite.config.js
const ReactCompilerConfig = { /* ... */ };export default defineConfig(() => {return {plugins: [react({babel: {plugins: [["babel-plugin-react-compiler", ReactCompilerConfig],],},}),],// ...};
});
Next.js :
参阅 Next.js 文档
Remix
安装 ,并向其添加编译器的 Babel 插件:vite-plugin-babel
npm install vite-plugin-babel
// vite.config.js
import babel from "vite-plugin-babel";const ReactCompilerConfig = { /* ... */ };export default defineConfig({plugins: [remix({ /* ... */}),babel({filter: /\.[jt]sx?$/,babelConfig: {presets: ["@babel/preset-typescript"], // if you use TypeScriptplugins: [["babel-plugin-react-compiler", ReactCompilerConfig],],},}),],
});
Webpack
社区 webpack loader已提供。
故障 排除
要报告问题,请首先在 React Compiler Playground 上创建一个最小重现,并将其包含在你的错误报告中。您可以在 facebook/react 存储库中打开问题。
你也可以通过申请成为成员在 React 编译器工作组中提供反馈。有关 加入的更多详细信息,请参阅 README。
编译器假定什么?
React 编译器假定你的代码:
- 是有效的语义 JavaScript。
- 测试在访问可空/可选值和属性之前是否定义它们(例如,如果使用 TypeScript,则通过启用 strictNullChecks ),即或使用 optional-chaining 。
if (object.nullableProperty) { object.nullableProperty.foo }object.nullableProperty?.foo
- React 的规则。
React Compiler 可以静态验证 React 的许多规则,并在检测到错误时安全地跳过编译。要查看错误,建议同时安装 。eslint-plugin-react-compiler。
如何知道我的组件已优化?
React DevTools (v5.0+) 和 React Native DevTools内置了对 React 编译器的支持,并将在编译器优化的组件旁边显示 “Memo ✨ ” 徽章。
编译后某些内容无法正常工作
如果你安装了 eslint-plugin-react-compiler,编译器会在你的编辑器中显示任何违反 React 规则的行为。当它这样做时,这意味着编译器跳过了优化该组件或 hook。这是完全可以的,编译器可以恢复并继续优化代码库中的其他组件。你不必立即修复所有 ESLint 冲突。您可以按照自己的节奏解决这些问题,以增加要优化的组件和 hook 的数量。
然而,由于 JavaScript 的灵活和动态特性,不可能全面检测所有情况。在这些情况下,可能会出现错误和未定义的行为,例如无限循环。
如果你的 app 在编译后无法正常工作,并且你没有看到任何 ESLint 错误,则编译器可能错误地编译了你的代码。为了确认这一点,请尝试通过 “use no memo” 指令
主动选择退出您认为可能相关的任何组件或 hook,从而使问题消失。
function SuspiciousComponent() {"use no memo"; // opts out this component from being compiled by React Compiler// ...
}
注意
“use no memo”
"use no memo"是一个临时的转义舱口,允许你选择退出 React 编译器编译的组件和钩子。这个指令并不意味着像 use client 那样长寿。除非绝对必要,否则不建议使用该指令。一旦你选择退出一个组件或 hook,它就会永远选择退出,直到该指令被删除。这意味着,即使您修复了代码,编译器仍将跳过编译它,除非您删除该指令。
#如果你觉得这篇文章对你有帮助,请点赞 👍、收藏 👏 并关注我!👀
当您使错误消失时,请确认删除 opt out 指令会使问题再次出现。然后使用 React Compiler Playground 与React共享错误报告(您可以尝试将其简化为一个小的复制,或者如果它是开源代码,您也可以直接粘贴整个源代码),以便官方识别并帮助解决问题。
如果你觉得这篇文章对你有帮助,请点赞 👍、收藏 👏 并关注我!👀
相关文章:

React 编译器
🤖 作者简介:水煮白菜王,一位前端劝退师 👻 👀 文章专栏: 前端专栏 ,记录一下平时在博客写作中,总结出的一些开发技巧和知识归纳总结✍。 感谢支持💕💕&#…...

HCIP:MPLS静态LSP的配置及抓包
目录 一、MPLS的简单的一些知识点 1.MPLS的概述: 2.MPLS工作原理: 3.MPLS的核心组件: 4. MPLS标签 5.MPLS标签的处理 6.MPLS转发的概述: 7.MPLS的静态LSP建立方式 二、MPLS的静态LSP的实验配置 1.配置接口的地址和配置OS…...

VASP 教程:VASP 结合 Phonopy 计算硅的比热容
VASP 全称为 Vienna Ab initio Simulation Package(The VASP Manual - VASP Wiki)是一个计算机程序,用于从第一性原理进行原子尺度材料建模,例如电子结构计算和量子力学分子动力学。 Phonopy(Welcome to phonopy — Ph…...
YOLO使用SAHI进行小目标检测
目录 一、环境配置二、使用ultralytics的YOLO模型进行训练和推理三、推理可视化的两种方法四、使用SAHI和ultralytics 训练的YOLO模型进行推理一、环境配置 下面是环境的配置过程,根据代码复杂度可以额外安装其他包。 #创建虚拟环境 conda create -n 环境名 python=3.9 #开启…...

[论文阅读]Prompt Injection attack against LLM-integrated Applications
Prompt Injection attack against LLM-integrated Applications [2306.05499] Prompt Injection attack against LLM-integrated Applications 传统提示注入攻击效果差,主要原因在于: 不同的应用对待用户的输入内容不同,有的将其视为问题&a…...
【SpringCache 提供的一套基于注解的缓存抽象机制】
Spring 缓存(Spring Cache)是 Spring 提供的一套基于注解的缓存抽象机制,常用于提升系统性能、减少重复查询数据库或接口调用。 ✅ 一、基本原理 Spring Cache 通过对方法的返回结果进行缓存,后续相同参数的调用将直接从缓存中读…...

DALI DT6与DALI DT8介绍
“DT”全称Device Type,是DALI-2 标准协议中的IEC 62386-102(即为Part 102)部分对不同类型的控制设备进行一个区分。不同的Device Type代表不同特性的控制设备,也代表了这种控制设备拥有的扩展的特性。 在DALI(数字可寻址照明接口)…...

day13 leetcode-hot100-24(链表3)
234. 回文链表 - 力扣(LeetCode) 1.转化法 思路 将链表转化为列表进行比较 复习到的知识 arraylist的长度函数:list.size() 具体代码 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode ne…...
Python实战:打造高效通讯录管理系统
📋 编程基础第一期《8-30》–通讯录管理系统 📑 项目介绍 在信息化时代,高效管理个人或团队联系人信息变得尤为重要。本文将带您实现一个基于Python的通讯录管理系统,该系统采用字典数据结构和JSON文件存储,实现了联系…...

图解深度学习 - 基于梯度的优化(梯度下降)
在模型优化过程中,我们曾尝试通过手动调整单个标量系数来观察其对损失值的影响。具体来说,当初始系数为0.3时,损失值为0.5。随后,我们尝试增加系数至0.35,发现损失值上升至0.6;相反,当系数减小至…...

MySql--定义表存储引擎、字符集和排序规则
示例: CREATE TABLE users (id INT PRIMARY KEY,name VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci,email VARCHAR(100) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci;注意事项: 字符集和排序规则可以按列覆盖表…...
【部署】在离线服务器的docker容器下升级dify-import程序
回到目录 在离线服务器的docker容器下升级dify-import程序 dify 0.1.0-release 变化很大,重构整个项目代码并且增加制度类txt文件知识库父子分段支持,详见 读取制度类txt文件导入dify的父子分段知识库(20250526发布). 。下面是kylin Linux环境下&#…...

优化版本,增加3D 视觉 查看前面的记录
上图先 运来的超出发表上限,重新发。。。 #11:06:57Current_POS_is: X:77Y:471Z:0U:-2 C:\Log\V55.txt import time import tkinter as tk from tkinter import messagebox from PIL import Image, ImageTk import socket import threading from date…...
写作-- 复合句练习
文章目录 练习 11. 家庭的支持和老师的指导对学生的学术成功有积极影响。2. 缺乏准备和未能适应通常会导致在挑战性情境中的糟糕表现。3. 吃垃圾食品和忽视锻炼可能导致严重的健康问题,因此人们应注重保持均衡的生活方式。4. 昨天的大雨导致街道洪水泛滥,因此居民们迁往高地以…...

WWW22-可解释推荐|用于推荐的神经符号描述性规则学习
论文来源:WWW 2022 论文链接:https://web.archive.org/web/20220504023001id_/https://dl.acm.org/doi/pdf/10.1145/3485447.3512042 最近读到一篇神经符号集成的论文24年底TOIS的,神经符号集成是人工智能领域中,将符号推理与深…...

Linux:shell脚本常用命令
一、设置主机名称 1、查看主机名称 2、用文件的方式更改主机名称 重启后: 3、 通过命令修改主机名 重启后: 二、网络管理命令 1、查看网卡 2、设置网卡 (1)网卡未被设置过时 (2)当网卡被设定,…...
专业课复习笔记 11
从今天开始每天下午复习专业课。慢慢复习专业课。目标至少考一个一百分吧。毕竟专业课还是比较难的。要是考不到一百分,我感觉自己就废掉了呢。下面稍微复习一下计组。 复习指令格式和数据通路设计。完全看不懂,真是可恶啊。计组感觉就是死记硬背&#…...

OpenTelemetry × Elastic Observability 系列(一):整体架构介绍
本文是 OpenTelemetry Elastic Observability 系列的第一篇,将介绍 OpenTelemetry Demo 的整体架构,以及如何集成 Elastic 来采集和可视化可观测性数据。后续文章将分别针对不同编程语言,深入讲解 OpenTelemetry 的集成实践。 程序架构 Op…...

STM32高级物联网通信之以太网通讯
目录 以太网通讯基础知识 什么是以太网 互联网和以太网的区别 1)概念与范围 (1)互联网 (2)以太网 2)技术特点 (1)互联网 (2)以太网 3)应…...
从Java的Jvm的角度解释一下为什么String不可变?
从Java的Jvm的角度解释一下为什么String不可变? 从 JVM 的角度看,Java 中 String 的不可变性是由多层次的机制共同保障的,这些设计涉及内存管理、性能优化和安全保障: 1. JVM 内存模型与字符串常量池 字符串常量池(St…...
从零开始的数据结构教程(四) 图论基础与算法实战
🌐 标题一:图的表示——六度空间理论如何用代码实现? 核心需求 图(Graph)是用于表达实体间关系的强大数据结构,比如社交网络中的好友关系,或者城市路网的交叉路口连接。关键在于如何高效存储和…...

历年西安交通大学计算机保研上机真题
2025西安交通大学计算机保研上机真题 2024西安交通大学计算机保研上机真题 2023西安交通大学计算机保研上机真题 在线测评链接:https://pgcode.cn/school 计算圆周率近似值 题目描述 根据公式 π / 4 1 − 1 / 3 1 / 5 − 1 / 7 … \pi / 4 1 - 1/3 1/5 - …...
可视化与动画:构建沉浸式Vue应用的进阶实践
在现代Web应用中,高性能可视化和流畅动画已成为提升用户体验的核心要素。本节将深入探索Vue生态中的可视化与动画技术,分享专业级解决方案与最佳实践。 一、 Canvas高性能渲染体系 01、Konva.js流程图引擎深度优化 <template><div class"…...
Python |GIF 解析与构建(3):简单哈希压缩256色算法
Python |GIF 解析与构建(3):简单哈希压缩256色算法 目录 Python |GIF 解析与构建(3):简单哈希压缩256色算法 一、算法性能表现 二、算法核心原理与实现 (一…...
蓝桥杯2114 李白打酒加强版
问题描述 话说大诗人李白, 一生好饮。幸好他从不开车。 一天, 他提着酒显, 从家里出来, 酒显中有酒 2 斗。他边走边唱: 无事街上走,提显去打酒。 逢店加一倍, 遇花喝一斗。 这一路上, 他一共遇到店 N 次, 遇到花 M 次。已知最后一次遇到的是花, 他正好把酒喝光了。…...

基本数据指针的解读-C++
1、引言 笔者认为对于学习指针要弄清楚如下问题基本可以应付大部分的场景: ① 指针是什么? ② 指针的类型是什么? ③ 指针指向的类型是什么? ④ 指针指向了哪里? 2、如何使用指针 使用时的步骤如下: ① …...
Android Studio里的BLE数据接收策略
#本人是初次接触Android蓝牙开发,若有不对地方,欢迎指出。 #由于是讲接收数据策略(其中还包含数据发送的部分策略),因此其他问题部分不会讲述,只描述数据接收。 简介(对于客户端---手机端) 博主在处理数据接收的时候࿰…...
【Office】Excel两列数据比较方法总结
在Excel中,比较两列数据是否相等有多种方法,以下是常用的几种方式: 方法1:使用公式(返回TRUE/FALSE) 在空白列(如C列)输入公式,向下填充即可逐行比较两列(如…...

基于多模态脑电、音频与视觉信号的情感识别算法【Nature核心期刊,EAV:EEG-音频-视频数据集】
简述 理解情感状态对于开发下一代人机交互界面至关重要。社交互动中的人类行为会引发受感知输入影响的心理生理过程。因此,探索大脑功能与人类行为的努力或将推动具有类人特质人工智能模型的发展。这里原作者推出一个多模态情感数据集,包含42名参与者的3…...

【QueryServer】dbeaver使用phoenix连接Hbase(轻客户端方式)
一、轻客户端连接方式 (推荐) 演示无认证配置方式, 有认证填入下方有认证参数即可 1, 新建连接 → Hadoop/大数据 → Apache Phoenix 2, 手动配置QueryServer驱动: 填入: “类名”, “URL模版”(注意区分有无认证), “端口号”, (勾选无认证) 类名: org.apache.phoenix…...