Chrome DevTools 调试翻车?我翻了10个案例
翻了5年代码,总结10个真实翻车场景,手把手教你绕过去
调试这件事,老前端都知道——写代码半小时,调试一下午。Chrome DevTools 天天用,但大部分人只用了它 20% 的功能。剩下 80% 不是难,是没人告诉你怎么用。这篇文章不教你什么是 DevTools,教你我在真实项目里翻过的车,以及怎么爬起来。
假设你正在改一个接口返回的数据格式,发现前端拿到的字段跟你预期的不一样,你开始疯狂 console.log,刷新,看控制台,再 log。十分钟过去了,问题是找到了,但整个人已经麻了。这类场景,我翻了无数遍。今天把最典型的 10 个整理出来,附上真正的解法。
一、Console 翻车现场:console.log 只是个入门
案例1:对象被打印成 {...},值变了?
console.log(res) 打印一个请求回来的对象,控制台显示 {...},你展开一看——数据全变了,变成了请求完成后的状态,而不是请求那一刻的值。console.log(JSON.parse(JSON.stringify(obj))) 深度复制,或者直接用 console.table(arr) 把数组打出来,或者用断点卡住那一刻去看。案例2:console.log 打了十几行,分不清谁是谁
console.log('data:', data),刷新后控制台刷屏了,完全不知道哪行对应哪个调用栈。console.log('%c[API] data:', 'color:#4fc9c5;font-weight:bold', data) 不同模块用不同颜色,一眼区分。还可以用 console.group() / console.groupEnd() 给同一个操作的所有日志包成一个折叠组。console.table(arr) — 把数组/对象表格化,比 log 清晰一百倍console.time('task') / console.timeEnd('task') — 精确计时console.assert(condition, 'wrong!') — 条件触发才打印console.trace() — 打印调用栈,不用断点也能看堆栈console.count('label') — 计数器,统计某段代码执行了多少次
案例3:Error 被吞了,只看到 undefined
.catch() 吞掉了真实错误,只打印了个 TypeError: Cannot read property 'x' of undefined,但你根本不知道是哪个环节出的问题。.catch(err => { console.error('真实错误:', err); throw err; }),顺手把错误对象完整打出来,包括它的 stack 属性。或者在 Network 里看接口返回的实际错误信息,Console 里的 err 对象往往比你在业务代码里拿到的更详细。二、Network 翻车现场:过滤器和断点才是本体
案例4:接口列表刷屏,找到目标接口花了3分钟
method:POST 只看 POST 请求,status:4 过滤 4xx 错误,domain:api.example.com 只看指定域名。更直接:直接在过滤器输入框敲接口关键字,如果知道完整路径的话可以精准定位。另外按 Ctrl+F(Mac 是 Cmd+F)打开搜索,可以搜请求体里的内容。案例5:XHR 请求参数对不上,不知道哪里发了串改过的数据
xhr.url.includes('/api/orders'),每当匹配到这个接口的 XHR 请求发起就断住,此时可以看调用栈,顺藤摸瓜找到参数被改的那行代码。案例6:接口 4xx,但你不知道是因为参数校验失败还是 token 过期
三、Sources 翻车现场:断点不是只有「停在这一行」
案例7:异步代码断不住,Promise 链里断点根本不触发
.then() 里下了断点,但断点有时候触发有时候不触发,或者触发时变量值已经变了,完全无法调试异步流程。new Promise((resolve, reject) => {}) 这一行,它会在 Promise 实际执行时(不是创建时)停住,比在 .then 里下更稳。另外可以试试 Blackbox scripts 把第三方库脚本加入黑盒,避免断点跳进 node_modules 里。案例8:for 循环执行了 1000 次,你断点卡了 1000 次
i === 999,这样断点只在第 1000 次迭代时触发。或者直接写 条件断点(condition):i === 999,满足条件才停住。这两个功能用好了,循环调试效率直接翻 10 倍。案例9:线上代码想加 console.log,但没有源文件访问权限
四、Elements 翻车现场:改样式改 DOM 不算真本事
案例10:改了 Elements 里的样式,刷新就没了,想把改动保留到源码
五、Coverage 和 Memory:性能问题也要会查
Bonus:Coverage 不只是给你看百分比
很多人不知道 DevTools 还有一个 Coverage 面板(快捷键 Ctrl+Shift+P → 搜 "Coverage")。它能告诉你哪些 JS/CSS 代码实际被执行了、哪些是死代码。一个 200KB 的库如果 Coverage 显示只用了 30%,说明你可能引入了一个巨大的依赖但只用了一小部分功能——这就是优化空间。
使用方法:点击录制按钮刷新页面,操作完再点一次停止,DevTools 会展示每个文件的使用率。红色的部分就是可以优化或懒加载的代码。这个技巧在做首屏加载优化时特别有用。
Bonus:Memory 面板看泄漏
如果你的页面越用越卡,点击 Memory 面板 → Allocation instrumentation on timeline,录制一段操作后可以看到内存占用曲线。如果曲线只涨不跌,说明有内存泄漏。展开 heap 可以看是哪个对象占了大头,定位到闭包、DOM 引用或者 EventListener 没移除这类常见问题。
还有个实用技巧:Heap Snapshot 对比。操作前拍一张快照,操作后再拍一张,对比两次 Snapshot 的 retained size,哪个对象多了、哪个 DOM 节点没释放,一目了然。
总结:10 个案例,几个核心思路
翻来覆去,调试翻车的根因就那么几个:
- 不知道工具有多强 — console 家族、断点类型、Coverage、Memory 这些,不是功能少,是你知道得太少
- 在错误的地方调试 — 在 Console 里反复 log 本该用断点,在 Elements 里反复改样式本该用 Overrides
- 不知道什么时候该停下来 — 条件断点、Hit count 断点、XHR 断点,这些功能就是给「普通断点不够用」的场景准备的
- 改动无法落回源码 — Overrides 和 Workspaces 是解决这个问题的官方方案,很多人压根不知道这俩东西存在
DevTools 本身已经足够强了,欠缺的只是有人把这些真实翻车场景整理成文档。收藏这篇文章,下次调试翻车时回来对照着查,能省不少时间。
如果你觉得这篇文章有用,想系统性地提升前端效率,推荐看看 CloverTools 的开发者工具集合,涵盖从调试到构建的实用工具集,持续更新:
常见问题
A: 这类工具一般有明确的输入框和输出框,按提示输入内容,点击对应按钮即可得到结果。建议先用简单示例测试功能是否正常,再处理实际数据。
A: 根据具体工具类型决定。格式转换工具适合处理第三方数据,编码工具适合加密传输,压缩工具适合文件上传前处理。多积累工具使用经验,遇到问题时能快速判断用哪个工具解决。
A: 不同工具有不同侧重,重点是理解原理。可以同时安装多个类似工具,实际使用中对比效果,选择最顺手的一个。随着使用经验增加,你也能判断工具的好坏。