news 2026/8/22 16:09:08

chrome-react-perf自定义Redux中间件深度剖析:如何向被测页面注入Perf.start()命令

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
chrome-react-perf自定义Redux中间件深度剖析:如何向被测页面注入Perf.start()命令

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] }

中间件的处理流程非常清晰:

  1. 检查 action 是否带PERF_ACTION标记,没有就原样放行next(action)
  2. 判断类型属于injectedActions(即 Start / Stop 录制)走直接注入分支,否则走消息中继分支
  3. 先派发XXX_REQUEST更新 UI 状态(比如按钮变成 Stop)
  4. 执行结果以 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了(跨窗口传大数据不可靠),插件走了一条完整的消息中继链路:

  1. DevTools 面板:中间件passMessage(app/middleware/perf-action/message.js)通过chrome.runtime.connect建立 Port,向后台发送消息,并用actionsRecorder队列暂存 Promise 的 resolve/reject,等待响应
  2. 后台 Event Page(chrome/extension/background/eventPage.js):收到消息后根据 Port 找到对应 tabId,用chrome.tabs.sendMessage转发到页面
  3. Content Script(chrome/extension/content/contentScript.js):在扩展与页面之间"翻译"消息——chrome.runtime.onMessage收到后window.postMessage给页面,页面回复再chrome.runtime.sendMessage送回
  4. 页面脚本(chrome/extension/page/pageScript.js):在页面上下文执行shapeMeasurementsgetWasted() / 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 步让插件跑起来

  1. 安装扩展:从 Chrome 应用商店安装,或在本仓库执行npm installnpm run build构建(开发调试用npm run dev开启热重载)
  2. 暴露 Perf:在 React 应用入口加入import 'expose?Perf!react-addons-perf',或import Perf from 'react-addons-perf'后赋值给window.Perf
  3. 开始剖析:打开 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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/22 16:08:27

用普通摄像头免费做眼动追踪:eyeLike 零成本快速上手指南

用普通摄像头免费做眼动追踪:eyeLike 零成本快速上手指南 【免费下载链接】eyeLike A webcam based pupil tracking implementation. 项目地址: https://gitcode.com/gh_mirrors/ey/eyeLike eyeLike 是一个用 OpenCV(最常见的图像库)写…

作者头像 李华
网站建设 2026/8/22 16:06:41

小红书 算法一面 十三

Deepseek r1中的训练方式有什么特别之处?怎么做的think?RLHF的流程是什么? ## 一、DeepSeek R1 训练方式的核心特色与具体实现DeepSeek R1 是 DeepSeek 团队推出的大模型,其训练方式的核心创新是**将 MoE(混合专家&…

作者头像 李华
网站建设 2026/8/22 16:05:14

G-Helper AMD CPU降压完整指南:如何降温15℃、功耗省20%

G-Helper AMD CPU降压完整指南:如何降温15℃、功耗省20% 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook, …

作者头像 李华
网站建设 2026/8/22 16:04:27

[光学原理与应用-507]:光为什么会有偏振?从哲学的角度阐述

光偏振:哲学视角的解读物理事实作为根基:光是横电磁波,传播方向与电场振动方向互相正交;振动被约束在垂直行进方向的二维平面之内,这是偏振的物质基础。哲学不是推翻物理定律,而是对这一现象背后蕴含的存在…

作者头像 李华
网站建设 2026/8/22 16:03:15

Python进阶教程:11_pip 包管理工具 —— 新手完全指南

一、什么是 pip?1.1 一句话定义pip(Pip Installs Packages)是 Python 的官方包管理工具,用来安装、升级、卸载第三方库。1.2 生活比喻pip 手机上的"应用商店"PyPI(Python Package Index) 应用商…

作者头像 李华