Skip to content

Vue DevTools v9.0.0-beta.0 发布:基于 Vite DevTools 重写 ​

译注:本文翻译自 Vue DevTools 官方 GitHub Release,原文链接见文末。发布日期为 2026-09-22。

Vue DevTools v9 是对 Vue 调试界面的重写,构建于 Vite DevTools 与 Devframe 之上,作者为 @webfansplz(commit 4df831)。它保留了开发者熟悉的 Components / Pages / Timeline / Pinia / Router / Graph 工作流,并以 Vite 插件加 Chromium 扩展两种形式发布。

安装方式与插件 API 的变更请参阅迁移指南。

🚨 破坏性变更 ​

  • vite:要求 Vite 8.3.0+,并在项目级安装 @vitejs/devtools,且在 Vite 配置中设置 devtools: true。
  • vite:vite-plugin-vue-devtools 不再启动或标识共享的 DevTools 宿主;vueDevTools() 仅注册为 Vue dock。
  • vite:移除 componentInspector 与 launchEditor。组件检查功能移至 Vue dock;在编辑器中打开由 @vitejs/devtools 通过 vite:core:open-in-editor 负责。
  • vite:builtinViteDevTools 移至 devtools.builtinDevTools,embeddedVisibility / dockPreferences 移至 Vite 的 devtools 配置下。VueDevToolsDockPreferences 不再导出。
  • api:移除 Vue 层面的 addCustomTab、addCustomCommand 与 removeCustomCommand。请改用 Devframe 的 ctx.docks.register() 与 ctx.commands.register()。
  • 本发布线移除 overlay shell 与分屏布局。
  • 移除 Vite 的 Assets 标签页(项目文件浏览器)。

🚀 新特性 ​

  • 将客户端重建为 Vite DevTools dock,包含 Components、Pages、Timeline、Pinia、Router、Graph、Settings 与 Command Palette。
  • client:为选中组件提供响应式关系 Graph(Vue 3.6+):refs、computed、effects 及其依赖链接。
  • chrome:支持 frame 感知的 MV3 端口(tabId + frameId + documentId)与逐 frame 运行时,关闭 #687、#745、#984。
  • client:组件搜索支持正向词、-negative、tag:、file: 与 is:favorite,关闭 #304、#801、#1001、#1002。
  • client:跨刷新恢复选中组件,并按应用保留收藏,关闭 #467、#601。
  • client:Command Palette(Ctrl/Cmd/Alt+K)在 Vite dock 与 Chrome 面板间共享。
  • client:可选的渲染/更新闪烁提示,含挂载/更新耗时(默认关闭),关闭 #678、#699、#827。
  • kit:为 undefined / "undefined"、null、NaN/Infinity、BigInt、Symbol、Date、RegExp、Error、函数、Map/Set、Proxy、循环引用与类实例提供带类型的 state codec,关闭 #809、#906、#953、#1087、#1100。
  • kit:为自定义 inspector、_custom.actions、timeline 层与插件设置保留 v6 风格的插件安装 API,关闭 #761、#832、#918。
  • vite:appendTo 接受 string | RegExp | Array<string | RegExp>;每个模块最多注入一次客户端,关闭 #586。
  • vite:仅当宿主暴露 capabilities.openInEditor 时才支持在编辑器中打开,关闭 #746、#774、#1093。
  • runtime:高亮器改用 popover,使定位在打开的 <dialog> 元素上仍可用,关闭 #567、#892。
  • client:对 computed 状态提供重新计算操作(triggerRef),用于调试失效/丢失响应式的问题,关闭 #1041。
  • kit:未访问的 computed 值显示 not accessed,且不运行 getter,关闭 #535。

🐞 问题修复 ​

  • chrome:隔离 iframe / 微前端应用,并在导航、刷新、BFCache、frame 分离与面板关闭时拆除端口,关闭 #445、#926。
  • chrome:跳过非 HTML 文档(XML、下载、不支持的 scheme),关闭 #505。
  • kit:按插件 + 应用隔离插件 inspector/layer ID;某个插件出错不再拖垮整个客户端,关闭 #694。
  • kit:防止组件/inspector 状态在选中、卸载与重连之间泄漏,关闭 #668、#689、#1111。
  • kit:Store as global variable($tempN)暴露实时运行时句柄,而非截断的预览。
  • client:不再将普通状态字符串渲染为 HTML,关闭 #696。
  • kit:每个运行时监听器只有一个所有者,使重连/HMR 不再重复键盘或组件事件,关闭 #648。
  • kit:将格式错误的自定义 timeline 负载隔离到单个事件,关闭 #728。
  • client:树过滤器变化时保留展开/折叠状态;仍匹配 KeepAlive 的非活跃子节点,关闭 #787、#888、#1018。
  • client:恢复组件树的水平滚动条,关闭 #1001。
  • client:树使用 role=tree / treeitem 与 roving focus,关闭 #1018。
  • client:组件标签使用可区分 0 / O / 1 / I / l 的字体,关闭 #1124。
  • rpc:分离 Chrome 与 Vite 通道,双重安装不再劫持另一个 inspector,关闭 #1004。
  • runtime:在取消、路由变化、面板关闭与 dispose 时移除定位 overlay/监听器,关闭 #1058。
  • runtime:定位器 mouseover 使用捕获,使嵌套组件在 @mouseover.stop 下仍能高亮,关闭 #487。
  • kit:当 setup() 返回渲染函数或 JSX defineComponent 时,从 devtoolsRawSetupState / setupState / expose() 收集 setup 状态,关闭 #376、#853。
  • vite:dock/client 路由使用 Vite 解析后的 base,关闭 #803、#824、#914、#1013。
  • vite:不再订阅或解析无关的 HMR 负载,关闭 #1057。
  • vite:移除 vite-plugin-inspect / vite-hot-client / vite-dev-rpc,关闭 #1068。

⚡ 性能 ​

  • perf(kit):按深度加载组件树并按需展开,而非反复刷新整棵树;对可见树之外的更新跳过元数据与调度工作,除非其状态被检查。相关:#791。
  • perf(kit):使用惰性状态预览与分页子节点,避免首次检查时序列化整个大值。以惰性读取而非流式 JSON 关闭 #912。
  • perf(kit):用基于集合的子链接减少批量挂载/卸载的记账;按实例身份配对性能事件,使注册不会将结束事件滞留在强引用队列中。
  • perf(kit):在 4ms 时间片后让出调度工作,并在编码内置或插件负载前应用共享的 Timeline 速率限制。限制树深度、更新防抖、Timeline 缓冲与传输消息大小/背压。
  • perf(client):虚拟化树/列表,复用索引处理仅属性变化的树补丁,并将待处理 Timeline 事件与历史各限制为 5,000 条。每批最多处理 250 条,并显示丢弃事件标记。关闭 #901。
  • perf(runtime):仅在客户端附加时进行收集,并允许禁用 Timeline 录制/层。相关:#997。

剩余验证:#791 仍需有代表性的大型应用交互检查;#997 通过延迟收集与层控制解决,而非完全延迟运行时注入。浏览器/网络/GPU 与长时间会话相关报告(#709、#806、#817、#835、#909)不在本次关闭声明范围内。手动排除组件(#898)与 Timeline JSON 导出(#1043)未在此实现。

v8 与 v9 基准对比 — 约 1 万个组件 ​

样本:一棵包含 11,112 个 Vue 组件的树,每个分支 10 个子节点,外加 10,000 条根状态记录。对比最新 v8 main 与 v9,环境为 Apple M3 Pro / 18 GB RAM / macOS、无头 Chrome、Node.js 24,以及相同的 Vue 3.5 运行时。时间为预热后五次运行的中位数。

测量项v8v9
打开面板 → 组件树可见540.4ms188.9ms
批量更新 → 被检查状态绘制完成810.9ms174.8ms
批量更新期间主线程 CPU385.2ms111.7ms
挂载 11,111 个组件 → 树可见694.0ms298.3ms
选中根组件 → 状态绘制完成98.4ms87.6ms
展开一个分支 → 子节点绘制完成66.9ms100.2ms
事件洪峰期间停止 Timeline 录制3,577.8ms31.1ms
初始树负载2,064,622 bytes2,187 bytes
初始状态负载1,480,712 bytes10,217 bytes

UI 计时使用真实 iframe 面板,包含 RPC、延迟刷新与绘制,而非止步于 Vue nextTick。主线程 CPU 覆盖相同的 1.1 秒更新窗口。挂载从空树开始;组件测试关闭 Timeline 录制。

Timeline 使用相同的调度生产者(每 50ms 发出 250 条),并采用各版本的默认收集策略。这测量的是停止按钮的响应速度,而非相同的事件吞吐量:v9 会丢弃多余事件,而 v8 的生产者在负载下也会变慢。

初始负载测量的是首次响应,而非整树展开:v9 返回 12 个树节点与惰性状态预览。这减少了初始工作量,但可能使单个分支展开变慢,如上表所示。

原文链接 ​