跳到主要内容

profiling

作为 React 为开发者提供的 “性能分析开关” ,通过独立的入口设计实现 分析能力与生产代码的物理隔离 , 体现 React 对性能调试体验的重视。

一、作用

profiling.js (该文件入口)是一个专用构建入口文件,核心作用是:启用与 React DevTools Profiler 深度集成的性能分析能力 , 同时保持与标准 react-dom 完全一致的 API。

1. 核心功能

  • 增强渲染性能追踪
    • 内部启用 enableProfilerTimer 等标志,使 Fiber 架构在 commit 阶段自动记录组件渲染耗时、组件层级耗时等数据
    • 这些数据通过 React DevTools 的 Profiler 面板 可视化展示(火焰图、 ranked chart 等),帮助定位性能瓶颈
  • 保留标准 API : 导出的 ReactDOM.rendercreateRoot 等方法签名与标准入口完全相同,无需修改业务逻辑,仅需替换 import 路径
  • (历史关联)与 Scheduler Tracing 集成 : 在 React 16 - 17 时期,需配合 scheduler/tracingunstable_trace 使用(标记异步操作范围)。⚠️ 注意: React 18+ 已移除 scheduler/tracing ,此用法已废弃,但 profiling 入口扔有效支持 DevTools Profiler

2. 使用方法

import ReactDOM from 'react-dom/profiling';

3. 关键注意事项

  • 仅限开发/分析环境 : 因注入性能追踪逻辑,会带来显著运行时开销(约 10% - 30%), 严禁在生产环境使用。生产构建应使用标准 react-dom
  • react/profiling 区别
    • react/profiling (React 核心包入口)提供 <Profiler> 组件等 API
    • react-dom/profiling 专注 DOM 渲染层的底层的计时能力,二者协同工作
  • DevTools 依赖 : 数据通过安装 React DevTools 扩展才能可视化查看
  • 版本演进 : React 18+ 扔保留入口已支持 Profiler 功能,但移除了对 scheduler/tracing 的依赖,聚焦于 DevTools 集成

二、导出

if (process.env.NODE_ENV === 'production') {
// DCE check should happen before ReactDOM bundle executes so that
// DCE 检查应该在 ReactDOM 包执行之前进行,这样
// DevTools can report bad minification during injection.
// 开发工具可以在注入期间报告错误的压缩。
checkDCE();
module.exports = require('./cjs/react-dom-profiling.profiling.js');
} else {
module.exports = require('./cjs/react-dom-profiling.development.js');
}

三、工具

1. 检测开发环境

备注

为毛没有提取 checkDCE 到 "checkDCE.js" 文件,单纯的发牢骚

function checkDCE() {
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' ||
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function'
) {
return;
}
if (process.env.NODE_ENV !== 'production') {
// This branch is unreachable because this function is only called
// in production, but the condition is true only in development.
// Therefore if the branch is still here, dead code elimination wasn't
// properly applied.
// 这个分支是不可达的,因为这个函数只在生产环境中被调用,但是这个条件只在开发环境中为真。
// 因此如果这个分支仍然存在,说明死代码消除没有被正确应用。
// Don't change the message. React DevTools relies on it. Also make sure
// this message doesn't occur elsewhere in this function, or it will cause
// a false positive.
// 不要更改此消息。React DevTools 依赖它。同时确保这个消息,在该函数的其他地方不会出
// 现,否则会导致误报。
throw new Error('^_^');
}
try {
// Verify that the code above has been dead code eliminated (DCE'd).
// 验证上面的代码是否已被消除死代码 (DCE)。
__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);
} catch (err) {
// DevTools shouldn't crash React, no matter what.
// 不管怎样,开发者工具不应该让 React 崩溃。
// We should still report in case we break this code.
// 如果我们破坏了这段代码,仍然应该报告。
console.error(err);
}
}