前端页面出 bug,第一反应是打开 DevTools 的,基本都算入门了;但很多人只会用 Console 打印日志,遇到"样式不对""请求失败""页面卡顿"就抓瞎。DevTools 其实是一整套调试系统:Elements 改样式、Sources 打断点、Network 看请求、Performance 查卡顿。这篇文章用四个真实场景带你逐个玩转,看完你就能自己排查大部分前端问题。

1. 打开 DevTools:三种姿势

打开方式:在页面任意位置右键选择"检查";或者按 F12;或者 Ctrl + Shift + I(Mac 是 Cmd + Option + I)。打开后默认停在 Elements 面板,左侧是 DOM 树,右侧是样式。还有一个冷门技巧:按 Ctrl + Shift + C 可以直接进入"选取元素"模式,鼠标点哪里,DevTools 就定位到哪里——排查样式问题第一件事就是用它。

2. Elements:改样式、查布局

看到某个元素位置不对,别急着去改代码:先在 Elements 里选中它,右侧 Styles 面板会显示所有生效的 CSS 规则,以及它们来自哪个文件哪一行。直接在上面的样式框里改值,页面实时刷新——先在这里"实验",确认改法后再回编辑器落地,省掉一遍遍保存刷新的循环。

更进阶的玩法:选中元素后,DevTools 会给它画一个"盒子模型"示意(内容、内边距、边框、外边距),数值一目了然。配合右侧的 Computed 标签,能看到所有计算后的最终样式,排查"为什么我写的样式没生效"(多半是被更具体的规则覆盖了)特别好用。

// 在 Console 里操作选中的元素
// 先用 Ctrl+Shift+C 点选页面上的元素,再执行:
$0.style.border = '2px solid red';
$0.textContent = '临时改的文字';
$0.offsetParent; // 看看它的定位上下文是谁

Console 里的 $0 永远指向你最后选中的元素,$1 是上一个……这串"历史引用"让你可以在不写任何代码的情况下,快速实验各种修改。改完刷新页面,所有临时修改都会消失——这正是我们想要的"实验场"效果。

3. Console:不只是 console.log

Console 面板最常见的用法是打印,但 console 对象远不止 log 一个方法。数据多的时候用表格,量耗时用计时器,条件断言可以替代一长串 if:

const users = [
  { name: '小明', score: 92 },
  { name: '小红', score: 88 }
];
console.table(users);          // 数组变表格,一眼看清结构

console.time('循环耗时');       // 开始计时
let sum = 0;
for (let i = 0; i < 1000000; i++) { sum += i; }
console.timeEnd('循环耗时');    // 结束并打印耗时

console.assert(sum > 0, 'sum 应该大于 0'); // 条件为假才输出错误

console.table 打印对象数组时是格式化表格,比 log 输出的展开式对象好读得多;time/timeEnd 成对出现,夹在中间的代码执行耗时会被打印出来,是排查"哪段代码慢"的利器;assert 第一个参数为假时才打印第二个参数,适合在关键节点做"轻量校验"。

Console 还有一个常被忽略的配置:顶部的日志级别筛选(All levels / Verbose / Info / Warnings / Errors)。生产环境里一堆第三方库疯狂打印,把级别切到 Errors,世界立刻清净。另外勾上 "Preserve log",刷新页面时控制台记录不会被清空——排查"刷新后立刻报错"的问题,这个开关是必须的。

4. Sources:断点调试

Console 打印能解决七成问题,剩下三成(尤其是循环、异步逻辑)要靠断点。切到 Sources 面板,左侧是文件树,找到你的 JS 文件,在行号上点一下就有红色断点。写一个"找最大值"的函数,看看断点怎么帮你观察每一次循环:

function findMax(arr) {
  let max = arr[0];
  for (let i = 1; i < arr.length; i++) {
    if (arr[i] > max) {   // 在这里打个断点,观察每次循环的值
      max = arr[i];
    }
  }
  return max;
}

debugger; // 代码执行到这里自动暂停
console.log(findMax([3, 9, 2, 7]));

暂停后,右侧 Scope 面板显示所有局部变量的当前值,顶部的控制按钮可以"单步跳过"(执行当前行)、"步入"(进入函数内部)、"步出"(跳出函数)。把鼠标悬停在任何变量上也能直接看到值。断点比 log 强的地方在于:你可以慢慢看每一行执行前后的状态变化,而不是靠脑补。

5. Network:看清每一次请求

"接口没数据""图片加载失败""页面转圈"——这类问题全部在 Network 面板解决。打开面板后刷新页面,所有网络请求按时间列出:点开任意一条能看到请求头、响应头、响应体、耗时。常用操作:按类型过滤(XHR 就是接口请求)、按关键词搜索、点 Fetch/XHR 只看接口。

// 在 Console 里手动发起一个请求,观察 Network 面板
fetch('https://api.github.com/users/octocat')
  .then(res => res.json())
  .then(data => console.log('拿到数据:', data.login))
  .catch(err => console.error('请求失败:', err));

这个请求发出后,Network 面板会立刻出现一条记录,点开能看到状态码 200、耗时、响应内容。排查接口问题的固定动作:看状态码(404 路径错、500 后端挂、403 没权限)、看响应体(后端返回的具体报错)、看耗时(慢在哪一段)。还有一个实用开关:面板顶部的"禁用缓存",调试接口时勾上,保证每次请求都是最新的。

看请求还有两个进阶入口:一是 Initiator 列,点开能看到"这个请求是哪个函数发起的",顺着调用栈能一路追到业务代码;二是右键一条请求,选择 "Copy as cURL",会把请求完整还原成一条 curl 命令,拿去终端里跑、或者贴给后端同事复现问题都很好用。配合面板顶部的搜索框,还能在所有请求的响应内容里全文搜索——接口返回里的某个字段,几秒钟就能定位到是哪条请求带回来的。

6. Performance:页面卡顿的照妖镜

页面滚动掉帧、点击没反应,Console 不会告诉你为什么,但 Performance 面板会。点击录制按钮,操作一遍页面(滚动、点击),再点停止,会得到一条"火焰图":每一帧、每个函数的执行时间都摊开在上面。

// 用 Performance API 给代码段手动打点
performance.mark('start');
for (let i = 0; i < 100000; i++) {
  document.title = i;  // 频繁改 DOM,性能杀手
}
performance.mark('end');
performance.measure('循环耗时', 'start', 'end');
const entry = performance.getEntriesByName('循环耗时')[0];
console.log('这段代码花了', entry.duration, '毫秒');

performance.mark/measure 可以精确测量某段代码的耗时,配合 Performance 面板的时间线,能定位到"到底是哪个函数在拖慢页面"。火焰图里红色长条就是"主线程被占住"的地方,通常对应死循环或频繁操作 DOM——这是前端性能优化的第一现场。

7. 移动端模拟与更多技巧

点 DevTools 左上角的"设备模拟"图标(手机形状),页面会切到移动端视口。顶部的下拉框可以直接选 iPhone、Pixel 等设备,还能模拟触摸事件。更关键的是 Network 面板里的 节流 选项:选 "Slow 3G",就能在本地体验弱网用户的加载感受——很多"桌面好好的,手机打不开"的问题,一模拟就现形。

// 在模拟的移动端环境里,检查这些关键值
console.log('视口宽度:', window.innerWidth);
console.log('像素比:', window.devicePixelRatio);  // 2 表示高清屏
console.log('UA:', navigator.userAgent.slice(0, 60));

devicePixelRatio 是判断高清屏的依据(设计稿里的 @2x 图就是为它准备的),navigator.userAgent 能确认当前模拟的是哪个设备。除了上面这些,DevTools 还有两个高频彩蛋:右上角三个点菜单里的 "More tools" 有 Lighthouse(一键生成性能、可访问性体检报告)和 Coverage(找出没被用到的 CSS/JS,帮你瘦身)。

设备模拟里还能自定义:下拉框最下面选 "Edit" 可以添加自己的设备(自定义屏幕尺寸、DPR、UA),团队有统一测试机型时非常实用。想要更狠的调试,试试 "More tools" 里的 Sensors:可以伪造地理位置(测试地图类应用)、模拟设备朝向、甚至覆盖 devicePixelRatio——这些在真机上难复现的场景,在 DevTools 里都是下拉框的事。

8. 总结与练习

这篇文章你掌握了:用 Elements 实时改样式、用 Console 的花式打印方法、用 Sources 打断点单步调试、用 Network 排查请求问题、用 Performance 定位卡顿、用设备模拟复现移动端 bug。练手三题:

💡 调试的顺序感比技巧更重要:先 Elements 确认表现,再 Console 打印数据,再 Network 看请求,最后 Sources 断点——从外到内一层层缩小范围,永远比乱试快。