performance monitor可实时监控dom nodes总数:右下角三点→more tools>performance monitor启用浮层,显示含textnode、commentnode及shadow dom、iframe内所有已挂载节点数;操作闭环后曲线不回落即为泄漏,需重点排查未配对removechild的setinterval、未解绑事件监听器、全局缓存已移除节点三类代码。

怎么用 Performance Monitor 实时看 DOM Nodes 数
打开 DevTools 后,右下角三个点 → More Tools > Performance monitor,浮层自动挂底。它显示的 DOM Nodes 数字就是当前所有已挂载节点总数,含 textNode、commentNode,也包含 Shadow DOM 和 iframe 内节点——这比手写 document.querySelectorAll('*').length 更准,后者漏 head、漏注释、漏 iframe。
别等页面卡了才查,开着它边操作边盯:弹窗打开→关闭→等 1 秒,看曲线是否回落。不回落就是泄漏信号。
为什么 $$('*').length 比 document.querySelectorAll 更可靠
$$ 是 DevTools 内置命令,不是 JS API,它能穿透 Shadow DOM 和 iframe contentDocument,返回真实挂载节点数。而 document.querySelectorAll('*').length 在以下场景会严重偏低:
- 页面含
<web-component></web-component>且其内部有 Shadow DOM - 嵌了第三方地图或图表 iframe,其内节点完全不计入
- 服务端渲染后残留大量
<!-- comment -->,$$统计在内,querySelectorAll默认忽略
实测某 WebGL 游戏页,$$('*').length 是 3217,document.querySelectorAll('*').length 只有 684——差近 5 倍,漏掉的全是 iframe 里的 UI overlay 节点。
DOM 节点数飙高时优先排查哪三类代码
不是所有增长都算 bug,但以下三类基本等于泄漏,必须立刻定位:
-
setInterval里反复appendChild()却没配对removeChild():轮播图、实时状态条最常见 - Vue/React 组件卸载后,
addEventListener没解绑,节点被闭包强引用,变成detached状态(Memory 面板搜Detached DOM tree可见) - 全局
Map缓存了已移除节点,如window.nodeCache.set(id, el),但el.remove()后没同步delete
查的时候别只看总数,重点看操作闭环后是否回落:打开弹窗 → 关闭 → 等 1 秒 → 看 DOM Nodes 曲线有没有回到基线。回不去,就从这三类代码里挖。
CI 中如何自动化拦截超限 DOM 节点
靠人每次手动敲 $$('*').length 不现实,必须塞进测试流程:
- Playwright 断言:
expect(await page.$eval('body', el => $$('*').length)).toBeLessThan(2000) - 首屏专项校验:先
await page.waitForSelector('.main-viewport'),再执行$$('.main-viewport *:is(:visible)')计数,阈值设 ≤500 - 配合
page.metrics()抓LayoutDuration,当该值 > 40ms 且节点数 > 1800 时自动失败并截图
注意:2000 不是建议值,是低端安卓设备实测拐点——联发科 Helio A22 + 2GB RAM 上,节点数达 2000 后 layout 耗时从 15ms 跳到 60ms+,直接拖垮 60fps 渲染循环。这个数字必须硬控。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











