开关 SourceMap

项目开发中如果使用了WebpackVite等打包工具的时候,在 Chrome Dev Tools 中调试源代码时,调试的是我们编译之前的代码,因为我们对未编译的代码和SourceMap做了关联,但是真正运行的代码是我们编译后的代码,所以如果我们想在控制台查看、或者获取代码中的某个函数、变量的值,使用未编译前的变量是获取不到的,此时可以通过关闭SourceMap的方式来查看我们编译后的代码,在ChromeDevTools中执行command + shift + p ,输入命令sourcemaps,选择开启、或者关闭SourceMap

查找脱离文档的节点 Detached Node

脱离文档的节点意思就是这个节点没有渲染到document,但是却依然在内存中持续的存在这个节点对象,它会造成很多内存泄漏的问题,例如如下代码

window.nodes = [];
const onClick = () => {
  for (let i = 0; i < 1000; i++) {
    const element = document.createElement('div');
    window.nodes.push(element);
  }
}

该代码在每次 onClick 执行的时候, 都会创建 1000 个 div 节点,但是这些节点并没有被传添加到document,而是添加到了 window 对象上的 nodes 中,如果 window.nodes 没有被清空或者重置,那么就会被持续引用,无法回收,这样就很容易咋成内存泄漏问题。
通过ChromeDevTools查看脱离文档的节点,点击 Memory面板,选择Heap snapshot(堆快照)选项,接着点击左上角的开关,生成一个当前JS的内存快照,可以通过分析当前内存快照,或者进行一些操作后,再次生成一个快照来进行对比。

DOM断点

除了为 JS 添加断点,还可以再为 DOM 元素添加断点,当 DOM 元素发生变化时会触发断点,鼠标选中元素之后右键,选择 Break on选项,该选项下又有三个选项:

  • subtree modifications: 子元素发生变更时触发断点
  • attribute modifications: 元素属性更改时触发断点
  • node removal: 元素被删除时触发断点

    勾选选项后操作 dom,如果触发了我们勾选的那个断点,就会触发,如果使用了框架,那么断点一般会定位在框架内部,此时可以通过调用栈向上溯源来找到真正触发的位置。

debugger

有时候会在代码中写入 debugger来方便我们调试断点,当我们不想断点的时候除了在源码中移除debugger还可以直接在ChromeDevTools中取消断点,选中 debugger所在的那一行代码,然后右键选择Never pause here,意思是永远不要在这一行暂停,就可以取消断点了

另外有个更快捷的方法来取消所有的断点

不使用console API直接打印信息

选中我们需要console的位置,右键选择Add logpoint,然后输入我们想要打印的信息,就可以在控制台中打印了

然后输入我们想要打印的信息,用逗号隔开,支持运算符

演示:

条件断点

如下代码,我们想在 item的值为50的时候才进入断点,可以通过右键需要断点的这一行,选择 Add conditional breakpoint 来添加条件断点

const onClick = () => {
	Array.from({ length: 100 }).map((_v, i) => i).forEach(item => {
		console.log(item);
	});
}

演示:

Chrome中调试 NodeJS 程序

调试 NodeJs 程序除了在 VSCode 中调试以外,还可以直接使用 ChromeDevTools来进行调试,只需要在执行 Node 代码添加--inspect-brk参数

执行之后打开ChromeDevTools就可以看到多了一个 NodeJS图标,点击就可以打开调试工具了

有一个好处是我们可以直接在浏览器中调试 webpack或者vite,只需要找到对应框架的启动文件,使用 node命令来执行,并添加 --inspect-brk参数
调试 Webpack

node --inspect-brk node_modules/webpack/bin/webpack.js build

调试Vite

node --inspect-brk node_modules/vite/bin/vite.js

--inspect-brk参数也可以用于调试NodeJs子进程,只需要在调试时添加参数即可

child_process.fork('src/child.js', {
	execArgv: ['--inspect-brk']
})

利用setTimeout 调试 ToolTip

只需要在控制台执行下面代码,在debugger触发之前我们触发想要调试的操作就可以了

setTimeout(() => {
	debugger;
}, 4000);

演示:

模拟页面焦点仿真

https://twitter.com/samijaber_/status/1625258927888732161
image.png

debug 和 undebug

ChromeDevTools 为我们提供了两个调试用的工具函数,debugundebug,顾名思义分别是添加调试和消除调试,使用方式为传入我们想要调试的函数

 // 想要调试某个函数时,当 onFn 被执行的时候,会进入 onFn 内部的断点
debug(onFn);
 
// 想要取消函数断点时
undebug(onFn)

例如下面代码,当我们断点在①处时,我们可以在控制台获取上下文中的 onClick 函数

只需要在控制台执行debug(onClick) 就可以为onClick函数添加断点了,演示:

XHR 断点

获取 DOM 元素上绑定的事件

有两种方法,一种是通过getEventListeners方法,鼠标查看元素选中我们要查看的 DOM 元素①,$0就是我们当前选中元素的具体值,通过getEventListeners($0)就可以获取改元素上绑定的所有事件

第二种方法是通过Event Listeners 面板

  1. 选中我们要查看的元素
  2. 选择Event Listeners面板
  3. 取消勾选Ancestors可以过滤父元素带来的绑定事件
  4. Remove可以手动移除该事件

事件断点

事件断点就是给某个事件添加断点,当事件执行时,就会触发断点.
通过command+shift+p 打开命令行,输入 Event Listener Breakpoints 命令就可以打开事件面板,勾选上我们想要断点的事件就可以了。演示:

请求重发Replay XHR和拷贝

鼠标右键请求,选择 Replay XHR 就可以直接重新发送该请求,适用于联调时发送表单提交等请求

Copy 可以直接将当前请求的所有数据 Copy 出来,可以发送给后端让他们自己调试,也可以放到命令行或者其他请求工具中,编辑我们的请求信息直接发送请求,或者让测试提供给我们请求的信息,我们可以自己复现问题

ChromeDevTools 特殊变量和函数

* $0-$4: 代表我们最近五次选中的DOM 元素历史记录
* $_: 最近一次控制台执行的结果
* $: 可以通过`$('div')` 来选中某个元素,等价于 document.querySelector
* $$: 返回匹配到的元素数组 等价于 document.querySelectorAll

查看页面重绘状态

通过 Show paint rectangles 命令

TODO

https://mp.weixin.qq.com/s/3wjFs—CuIBkXsnyKRkAJQ
细数那些不为人知的 Chrome DevTools 骚操作 - 知乎