chrome-react-perf自定义Redux中间件深度剖析:如何向被测页面注入Perf.start()命令
【免费下载链接】chrome-react-perfAn Operation Interface for react-addons-perf Package项目地址: https://gitcode.com/gh_mirrors/ch/chrome-react-perf
chrome-react-perf 是一款 React 性能剖析 Chrome 扩展,它的核心是一套自定义 Redux 中间件:在 DevTools 面板点击 Start,中间件就会向被测页面注入Perf.start()命令开始录制,点击 Stop 后自动生成渲染性能报告。本文带你剖析这套中间件的实现原理与消息回传链路。
chrome-react-perf 是什么:React 性能剖析小助手
普通开发者排查 React 性能问题时,通常要手动在控制台执行Perf.start()、Perf.stop(),再调用getWasted()等方法看数据,过程繁琐且容易遗漏。
chrome-react-perf 把这些操作封装进了 Chrome DevTools 的一个独立面板(Perf 面板):
- ⚡ 一键 Start / Stop 录制,停止时自动展示性能报告
- ✅ 关闭 Perf 面板时自动停止录制,不会污染页面
- 📊 数据维度覆盖 wasted(浪费的渲染)、DOM、inclusive(含子组件)、exclusive(独占)四类指标
它对被测页面只有一个前提:页面必须把react-addons-perf暴露为全局变量window.Perf(用 webpack 的 expose loader 或直接window.Perf = Perf即可)。
一条 Action 如何驱动整个插件:Redux 中间件设计
传统 Redux 中间件拦截的是"异步请求类"action,而这里拦截的是"跨环境执行类"action。中间件位于 app/middleware/perf-action/index.js,它用一个 Symbol 作为标记:
export const PERF_ACTION = Symbol('PERF_ACTION');所有特殊 action(定义在 app/actions/index.js)都不带常规的type,而是携带一个[PERF_ACTION]载荷,内含三种类型:
{ types: [XXX_REQUEST, XXX_SUCCESS, XXX_FAILURE] }中间件的处理流程非常清晰:
- 检查 action 是否带
PERF_ACTION标记,没有就原样放行next(action) - 判断类型属于
injectedActions(即 Start / Stop 录制)走直接注入分支,否则走消息中继分支 - 先派发
XXX_REQUEST更新 UI 状态(比如按钮变成 Stop) - 执行结果以 Promise 返回:成功则派发
XXX_SUCCESS并携带 response 数据,失败则派发XXX_FAILURE
这套"REQUEST / SUCCESS / FAILURE 三段式 + Promise"的写法,让异步的跨窗口执行被无缝纳入了 Redux 状态流。
核心揭秘:如何用 inspectedWindow.eval 注入 Perf.start()
注入逻辑在 app/middleware/perf-action/inject.js 中,核心就是一张命令映射表:
[ActionTypes.START_RECORD_REQUEST]: 'Perf.start()', [ActionTypes.STOP_RECORD_REQUEST]: 'Perf.stop()',真正的"注入"由 Chrome DevTools API 完成:
chrome.devtools.inspectedWindow.eval(command, callback)inspectedWindow.eval相当于在被测页面的 JS 环境里直接执行一段代码——中间件把'Perf.start()'这个字符串送进去,页面里的window.Perf就开始收集渲染指标了。回调结果被包装成 Promise:isException为真则 reject(页面没暴露 Perf 时就会走到这里),否则 resolve。
这就是"如何向被测页面注入Perf.start()命令"的答案:Redux action → 中间件映射成命令字符串 → DevTools API 在页面上下文执行。
数据回传链路:从页面脚本到 DevTools 面板
Stop 之后要读取getWasted()等数据,就不能只用eval了(跨窗口传大数据不可靠),插件走了一条完整的消息中继链路:
- DevTools 面板:中间件
passMessage(app/middleware/perf-action/message.js)通过chrome.runtime.connect建立 Port,向后台发送消息,并用actionsRecorder队列暂存 Promise 的 resolve/reject,等待响应 - 后台 Event Page(chrome/extension/background/eventPage.js):收到消息后根据 Port 找到对应 tabId,用
chrome.tabs.sendMessage转发到页面 - Content Script(chrome/extension/content/contentScript.js):在扩展与页面之间"翻译"消息——
chrome.runtime.onMessage收到后window.postMessage给页面,页面回复再chrome.runtime.sendMessage送回 - 页面脚本(chrome/extension/page/pageScript.js):在页面上下文执行
shapeMeasurements的getWasted() / getDOM() / getInclusive() / getExclusive(),把结果postMessage回来
数据原路返回后,actionsRecorder中的 Promise 被 resolve,中间件派发GET_PERF_DATA_SUCCESS,面板就能渲染出报告了。整条链路用source: 'chrome-react-perf'和sender字段做消息过滤,避免无限循环派发——细节见 chrome/extension/content/contentLoader.js 的初始化握手。
两个体验细节:启动检测与自动清理
- 🔍Perf 就绪检测:内容脚本被动态注入后(chrome/extension/background/injectContent.js),页面脚本会每 500ms 轮询一次
window.Perf是否存在,找到后通过detect-perf消息上报,中间件再派发detectPerfaction 更新 UI。页面是懒加载 Perf 的场景也不会出错。 - 🧹关闭面板自动 Stop:后台监听 Port 的
onDisconnect事件,检测到面板关闭且 Perf 曾就绪时,向页面发送clean-up消息,页面脚本随即调用window.Perf.stop(),避免遗留的录制状态干扰页面。
上手指南:3 步让插件跑起来
- 安装扩展:从 Chrome 应用商店安装,或在本仓库执行
npm install后npm run build构建(开发调试用npm run dev开启热重载) - 暴露 Perf:在 React 应用入口加入
import 'expose?Perf!react-addons-perf',或import Perf from 'react-addons-perf'后赋值给window.Perf - 开始剖析:打开 DevTools 的 Perf 面板,点击 Start → 操作页面触发渲染 → 点击 Stop,性能报告自动呈现
小结
chrome-react-perf 用一个精巧的自定义 Redux 中间件,把"向被测页面注入Perf.start()/Perf.stop()命令"这件跨窗口、跨环境的脏活变成了纯粹的 action 派发:简单命令走inspectedWindow.eval直接注入,复杂数据走 Port + 消息中继回传,三段式 action 类型保证状态与 UI 始终一致。想研究 Chrome 扩展如何与 Redux 状态管理深度协作,这套perf-action中间件(app/middleware/perf-action/)值得逐行阅读。
【免费下载链接】chrome-react-perfAn Operation Interface for react-addons-perf Package项目地址: https://gitcode.com/gh_mirrors/ch/chrome-react-perf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考