Chrome DevTools 小汇总记录

500 阅读9分钟

1 介绍

Chrome 开发者工具(简称 DevTools)是一组网页制作和调试的工具,内嵌于 Google Chrome 浏览器中。DevTools 使开发者更加深入的了解浏览器内部以及他们编写的应用。通过使用 DevTools,可以更加高效的定位页面布局问题,设置 JavaScript 断点并且更好的理解代码优化。


2 打开方式

  • 常规方式

    • 在浏览器窗口的右上方选择 Chrome 菜单, 然后选择工具 > 开发者工具
    • 再页面上任意位置, 右键 > 检查
  • 快捷键方式

    • DevTools(默认上次打开的功能俎)

      • mac: command + option + i
      • windows: control + shift + i
    • 控制台

      • mac: command + option + j
      • windows: control + shift + j
    • element(元素审查)

      • mac: command + option + c / command + shift+C
      • windows: control + shift + c

3 面板组成

  1. element
  2. console
  3. sources
  4. network
  5. application
  6. performance(性能分析)
  7. memory(内存)
  8. security(安全)
  9. Lighthouse(页面分析)

3.1 element

3.1.1. HTML 面板(元素)

3.1.1.1 元素选择
  • 点击检查元素 icon (面板左上角箭头,快捷键:command + shift + c),鼠标在页面中选中元素背景被高亮成蓝色
  • 打开开发者工具,点击 dom 树的某个元素节点,选中节点的背景被高亮成蓝色。
  • 页面鼠标移动到元素 > 右键 > 检查 > 打开开发者工具后自动将鼠标定位的元素选中,背景高亮成蓝色。
  • 在 console 面板中执行 document 相关 dom 查询
3.1.1.2 交换位置
  • drag 拖拽
  • 快捷键上下移动
    mac: command + [⬆] / command + [⬇]
    win: control + [⬆] / control + [⬇]
3.1.1.3 删除
  • 选中元素,按 delete
  • 右键 -> Delete element
3.1.1.4 选中
  • add attribute: 增加属性

  • edit attribute: 修改属性(只有当指针处于属性上才会显示)

  • edit as html 当成 html 编辑,可以随意更改

  • duplicate element 拷贝一份当前 div 并放置下方

  • delete element 删除节点

  • copy

    • cut、copy、paste
    • copy outreHTML 复制 html 内容
    • copy selector 复制 CSS Selector
    • copy js path 直接复制成 js 代码,指向当前节点
    • copy styles 支持 css 属性
    • copy xpath 获取相对路径
    • copy full xpath 获取绝对路径
      -Hide element 隐藏节点
  • force state 点击状态

  • Break on

    • subtree modifications 子树修改
    • attribute modifications 属性修改
    • node removal 删除节点
  • expand recursively 递归展开

  • Collapse children 折叠子项

  • Capture node screenshot 节点截图

  • Scroll into view 滑动到节点位置

  • Focus 聚焦

  • Store as global variable 存为全局变量

3.1.1.5 Tips!!!
  • 显示、隐藏元素
    场景:可以按下'h'来隐藏在元素面板中被你选中的元素,再次按下'h'使它出现。某些时候这是很有用的,例如你想截图,但是又不想里面包含一些敏感信息

  • 快速控制节点的展开与折叠
    左键(left):折叠子元素;
    右键(right):展开子元素;
    [⬆]/[⬇]:上下选择节点;

  • 命令菜单

    1. command + shift + p 打开命令菜单

    • 截屏快捷键

      • 输入 screenshot

      • 选择对应的方式

        • Capture area screenshot: 截取选择区域
        • Capture full size screenshot: 整页截屏
        • Capture node screenshot:捕捉选中节点
        • Capture screenshot: 捕捉页面可视区的内容
    • 改变窗口位置

      • 输入 dock
        undock 独立窗口
  • console 中快速打印节点

    • 0 0~4:最近选择过的 5 个 DOM 节点。0返回最近一次选择的DOM节点(或当前节点),以此类推,0 返回最近一次选择的 DOM 节点(或当前节点),以此类推,1 返回上上次选的 DOM 节点。最多可保存 5 个,如果不满 5 个,则返回 undefined。
    • Store as global variable:将元素存储为全局变量,保存之后节点的全局变量名为 temp1、temp2...以此类推。
  • $_ 返回上一条语句的返回结果

3.1.2. DOM 样式(CSS)、结构

3.1.2.1 styles
  • 选中类 > 点击空白 > 输入样式(输入之后按 Enter 保存样式)
  • color 颜色选择器(鼠标点击颜色方块会出现颜色选择器)
    改变颜色格式:在颜色预览中用 Shift + Click,可以在 rgba,hsl 和 hexadecimal(十六进制)这三种格式中切换。
  • auto-complete: 自动补全
3.1.2.2 computed 窗格
3.1.2.2.1 查看元素盒模型
  • 查看 width、height、padding、border、margin...度量单位可以是 px、百分比、vm 等。
3.1.2.2.2 关于 computed 中的样式
  • 显示顺序是按字母顺序显示
  • 显示的是真正作用在元素上的样式:style 中的样式可能是全部的样式,包括一些不起作用的样式。可实时查看更新样式是否生效。
  • 查看继承的 css 属性
  • 勾选 computed 中的 show all 复选框,展示元素所有的属性样式。
  • 通过 filter 可以过滤/查找某些属性/值(styles、computed...都有这个选项)
3.1.2.2.3 EventListeners

当前 dom 下的事件

3.1.2.2.4 Properties

查看元素具有的方法与属性,比查 API 手册要方便。

3.2 console

3.2.1 打开方式

  • command + option + j / control + shift + i
  • 处于其他面板时:command + shift + p > 搜索 console > 选择 Drawer Show Console

3.2.2 Console 对象(宿主环境提供)

  • console.log()/console.info: 输出信息
console.log(123); // 123
// 支持的占位符有:(样式)%c 字符(%s)、整数(%d或%i)、浮点数(%f)和对象(%o
console.log("%c样式", "color: red; font-size: 20px");
// 多种样式
console.log("%cBlue! %cRed!", "color: blue;", "color: red;");
console.log("%d年%d月%d日", 2011, 3, 26); // 2011326日
console.log("%o", { a: { b: { c: [1, 2, 3] } } });
console.log("%O", { a: { b: { c: [1, 2, 3] } } });
  • console.dir():将一个对象以 JSON 表达式的格式打印
  • console.warn(): 警告信息
  • console.error(): 输出信息时,在最前面加一个红色的叉,表示出错,同时会显示错误发生的堆栈
  • console.assert():接受两个参数,第一个参数是表达式,第二个参数是字符串。只有当第一个参数为 false,才会输出第二个参数,否则不会有任何结果
console.assert(true === false, 123); // Assertion failed: 123
console.assert(1 == true, 123);
  • console.count(): 计数,输出它被调用了多少次
  • console.countReset(): 重制
(function () {
  for (let i = 0; i < 5; i++) {
    console.count("count");
  }
})();
// count: 1
// count: 2
// count: 3
// count: 4
// count: 5
for (let i = 0; i < 10; i++) {
  if (i === 5) {
    console.countReset();
  } else {
    console.count();
  }
}
// default: 1
// default: 2
// default: 3
// default: 4
// default: 5
// default: 1
// default: 2
// default: 3
// default: 4
  • console.group(): 用于将显示的信息分组,可以把信息进行折叠和展开。
console.group("第一层");
console.group("第二层");
console.log("error");
console.error("error");
console.warn("error");
console.groupEnd();
console.log("error");
console.error("error");
console.warn("error");
console.groupEnd();
  • console.table(): 将复合类型的数据转为表格显示。
  • console.time(): 用于计时
console.time("计时器1");
for (let i = 0; i < 100; i++) {
  for (let j = 0; j < 100; j++) {}
}
console.timeEnd("计时器1");
console.time("计时器2");
for (let i = 0; i < 1000; i++) {
  for (let j = 0; j < 1000; j++) {}
}
console.timeEnd("计时器2");
  • console.trace() 追踪函数的调用过程
function d(a) {
  console.trace();
  return a;
}
function b(a) {
  return c(a);
}
function c(a) {
  return d(a);
}
let a = b("123");
  • cosnsole.profile: 性能分析,就是分析程序各个部分的运行时间,找出瓶颈所在(菜单面板 > profile)
function All() {
  alert(1);
  for (let i = 0; i < 10; i++) {
    funcA(10000);
  }
  funcB(10000);
}
function funcA(count) {
  for (let i = 0; i < count; i++) {}
}
function funcB(count) {
  for (var i = 0; i < count; i++) {}
}
console.profile("性能分析器");
All();
console.profileEnd();
  • clear(): 清空控制台

3.2.3 Tips!!!

  • console 代码换行:Chrome 控制台回车默认是执行,要想输入换行,应按 Shift + Enter
  • copy():复制一个具体对象的字符串表达式到剪切板,如 copy($0)
  • getEventListeners(document.documentElement)返回在 DOM 元素上注册的所有的事件
  • preserve log 保留历史记录, 打开后 clear()
  • monitorEvents(): 会输出指定监控目标的事件信息。该方法的第一个参数表示被监控的对象,第二个参数表示要监控的事件,如果不填则会默认返回该对象上所有事件的监控信息。你可以将数组传入第二个参数,来同时监控多个事件。

3.3 sources

3.3.1 组成

  1. 文件导航窗格:列出了页面请求的每个文件;
  2. 代码编辑窗格:在文件导航窗格选择文件后,代码编辑窗格会显示选中文件的内容;
  3. js 调试窗格:检查页面 js 的各种工具。

3.3.2 js 调试窗格

  • 调试按钮从左到右:

    1. 暂停/继续脚本执行:如果一个函数里有大量代码,但是大部分代码与定位的问题无关,点击该按钮(或者光标放到下一个要执行的断点行然后右键选择 continue to here 可以直接到该行的 debugger)可用于跳过冗长的代码片段,执行到下一个断点处(与定位问题相关的代码处)。
    2. 单步调试(快捷键 f10):不遇到函数,执行下一步;遇到函数,不进入函数,直接执行下一步;
    3. 进入函数调试(快捷键 f11):不遇到函数,执行下一步;遇到函数,进入函数执行上下文;
    4. step 下一步(遇到函数会进入)
    5. 跳出当前函数;
    6. 禁止所有的断点,停止任何调试;
    7. 程序运行遇到异常时是否中断调试: 当启动此功能并且开发者工具是打开着的时候,任何一个脚本的错误都会导致该脚本执行自动暂停。然后我们可以分析变量来看一下什么出错了。因此如果我们的脚本因为错误挂掉的时候,我们可以打开调试器,启用这个选项然后重载页面,查看一下哪里导致它挂掉了和当时的上下文是什么。
  • scope: 作用域链(代码中有闭包时 scope 窗格关注会多些,比如调试闭包中的 this 指向)。

  • breakpoints: 设置的断点全部显示在这里,可以快速定位到文件中断点的位置。

  • XHR/fetch breakpoints: 发请求的断点,比如可以在发 ajax 请求中打的断点。

  • DOM Breakpoints: js 改变 dom 节点属性、dom 节点子节点树改动、移除 dom 节点操作时打的断点全部显示在这个窗格。

  • global listeners: 全局监听器,在浏览器中 window 是全局对象,所以在 Global Listeners 面板中显示绑定在 window 对象上的事件监听。

  • event listener breakpoints:事件监听断点,比如鼠标的 click 事件,键盘 keydown 事件等。勾选事件前面的单选框即可监听该事件。

3.3.3 断点(在代码执行过程中暂停代码,同时检查所有相关的变量的值)

  • 添加断点的方式

    • 可以在代码里加 debugger 调试;
    • 在代码编辑窗格直接打断点
  • DOM 相关的断点

    • 子节点树改变、节点属性改变、节点移除
  • 条件断点(Conditional breakpoints)
    场景:有时设置的断点被执行太多次了:比如有一个对 200 个元素的循环,但我们只对第 110 次循环的结果感兴趣,或者只对一些满足其他的特殊条件的结果感兴趣,这样的情况下就可以设置一个条件断点。
    操作:

    1. 右击行号并且选择 Add conditional breakpoint(添加条件断点)的选项
    2. 或者右击一个已经设置的断点并且选择 Edit breakpoint(编辑断点)
    3. 然后输入一个执行结果为 true 或者 false 的表达式(它的值并不需要明确的为 true 或者 false,可以是表达式的结果为 true 或 false)。如果条件满足的话,断点就会暂停代码的执行
function test() {
  for (let i = 0; i < 100; i++) {
    console.log(i);
  }
}
test();

3.3.4 workspaces

将项目文件夹直接拖到 workspaces 面板,DevTools 会将对文件的修改同步到系统文件中

3.3.5 snippets

在任何页面创建、运行、保存代码段、小脚本

document.getElementsByClassName("feedback")[0].click();

3.3.6 Tips!!!

  • command + p: 直接定位到某一行

  • 快速查找文件&搜索特定字符串

  • 多列内容选择:按住 Opt 键,当鼠标箭头变为“+”号后,点击鼠标;

  • 匹配相同选项:选中需要匹配的元素,快捷键 Cmd + D

  • corverage:获取关于冗余代码的摘要-细节信息

    • 打开: 右下角/ corverage 命令
    • 打开 coverage 窗格,start 开始统计当前加载页面的代码,reload 按钮开始统计并重新加载页面
    • coverage 窗格展示了在浏览器加载时每个加载的 css 和 js 文件中有多少使用和未使用的部分。(绿色是已使用的,红色是未使用的)
    • 点击文件可以一行一行查看哪些部分被使用了哪些未被使用

3.4 network

3.4.1 工具栏

3.4.1.1 Preserve log(跨页面加载保存请求)

如页面跳转,勾选 Preserve log 复选框后 DevTool 会保存所有请求。

3.4.1.2 Disable cache(更改加载行为)

勾选 Disable cache 复选框可以停用浏览器缓存来模拟首次访问者,即可模拟新用户访问。
在其它面板中停用浏览器缓存:command menu 打开 Network conditions 抽屉,勾选/取消 Disable cache 复选框。

3.4.1.3 搜索/过滤网络日志:字符串搜索

按类型过滤请求:XHR、JS、CSS、Img、Media、Font、Doc、WS (WebSocket)、Manifest......

3.4.1.4 隐藏数据网址

数据网址是嵌入到其它文档中的小文件,在 Request 表格中看到的以 data:开头的所有请求都是数据网址,如图片的 base64 格式。

3.4.2 网络请求表格

  • Name:资源的文件名或标识符
  • Status:http 请求响应状态码
  • Type:资源类型
  • Initiator:启动源,发起请求的对象、进程,这些对象或进程包括 Parser、Redirect、Script、Other。(鼠标 hover 到该列可以看到调用堆栈的信息)
  • Size:响应头和响应内容组合的大小
  • Time:请求开始到从响应中接收到最终字节的总时间。
  • Waterfall:瀑布流,各请求相关活动的直观分析图。
  • content download:请求下载花费的时间
  • stalled: 请求会因为高优先级请求到达、和目标服务器已经建立了 6 个 TCP 连接等原因而阻塞

3.4.3 查看请求的详情

在 Request 表格的 Name 列下,点击请求的地址

3.4.4 查看请求的发起者和依赖项

按住 Shift,然后鼠标指针悬停在 Requests 表格中的请求上。绿色请求表示发起者,红色表示依赖项。

3.5 Application

Application 面板主要记录网站加载的所有资源信息,包括存储数据(Local Storage、Session Storage、IndexedDB、Web SQL、Cookies)、缓存数据、字体、图片、脚本、样式表等。

3.5.1 Application

  • Mainfest: manifest.json 文件,其作用是用来告诉浏览器如何在用户的桌面上"安装"这个 app,及安装后该展示的信息。在 Application 面板中,主要是展示其信息,不具有操作性质。 例如:demo

  • Service Workers: 是浏览器在后台独立于网页运行的脚本,它们已包括如推送通知和后台同步等功能,支持离线应用,每 24 小时都会更新本地的离线脚本。

    • 它是一种 JavaScript Worker,无法直接访问 DOM。 Service Worker 通过响应 postMessage 接口发送的消息来与其控制的页面通信,页面可在必要时对 DOM 执行操作。
    • Service Worker 是一种可编程网络代理,让您能够控制页面所发送网络请求的处理方式。
    • Service Worker 在不用时会被中止,并在下次有需要时重启
    • Service Worker 可以访问 IndexedDB。
  • Clear storage: 清除 Service Worker、Storage、数据库和缓存

3.5.2 Storage

3.5.2.1 Local Storage / Session Storage
  • 双击键或值可以修改相应的值。
  • 双击空白单元格可以添加新条目。
  • 点击对应的条目 ,然后按 Delete 按钮可以删除该该条目。
  • 点击 refresh 按钮可以查看您的更改。
3.5.2.2 IndexedDB 一种在用户浏览器中持久存储数据的方法。
const IDBOpenDBRequest = indexedDB.open("testDB", 1);
// 创建一个新的数据库或者增加已存在的数据库的版本号, 触发onupgradeneeded
IDBOpenDBRequest.onupgradeneeded = (e) => {
  const db = IDBOpenDBRequest.result;
  // 对象仓库
  const store = db.createObjectStore("User", {
    keyPath: "name",
  });
  // 对象属性
  store.createIndex("name", "name");
  store.createIndex("age", "age");
  store.createIndex("sex", "sex");
  const bookStore = db.createObjectStore("Class", {
    keyPath: "id",
    autoIncrement: true,
  });
  bookStore.createIndex("className", "className");
  bookStore.createIndex("classId", "classId");
  bookStore.createIndex("status", "status");
};
IDBOpenDBRequest.onsuccess = (e) => {
  const db = IDBOpenDBRequest.result;
  // 创建事务
  const transaction = db.transaction(["User", "Class"], "readwrite");
  // 访问对象仓库
  const objStore = transaction.objectStore("User");
  const objClassStore = transaction.objectStore("Class");
  // User 表加2条数据
  objStore.put({
    name: "xiaoming",
    age: 18,
    sex: 1,
  });
  objStore.put({
    name: "xiaohong",
    age: 18,
    sex: 2,
  });
  // Book 表加一条数据
  objClassStore.put({
    className: "一年级",
    classId: 1,
    status: 1,
  });
};
const transaction = IDBOpenDBRequest.result.transaction(["User"], "readwrite");
const objectStore = transaction.objectStore("User");
// 获取
const request = objectStore.get("xiaoming");
// 删除
objectStore.delete("xiaohong");
// 修改
request.onsuccess = (e) => {
  const data = e.target.result;
  data.age++;
  objectStore.put(data);
};
3.5.2.3 Cookies
  • name 键名
  • value 值
  • Domain 和 Path 标识定义了 Cookie 的作用域。Domain 标识指定了哪些主机可以接受 Cookie。Path 标识指定了主机下的哪些路径可以接受 Cookie
  • Expires / Max-Age. Cookie 的过期时间或最长周期。对于会话 cookie,这一领域始终是 Session(会话)。
  • Size Cookie 的大小,以字节为单位。
  • HttpOnly 如果存在,则指示应仅通过 HTTP 使用 cookie,并且不允许 JavaScript 修改.
  • SameSite Strict 允许服务器要求某个 cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)。Lax 则可以被发送
3.5.2.4 Web SQL 一组使用 SQL 操作客户端数据库的 APIs

openDatabase:这个方法使用现有的数据库或者新建的数据库创建一个数据库对象。
transaction:这个方法让我们能够控制一个事务,以及基于这种情况执行提交或者回滚。
executeSql:这个方法用于执行实际的 SQL 查询

const db = openDatabase("testdb", "1.0", "Test DB", 2 * 1024 * 1024);
db.transaction((tx) => {
  tx.executeSql("CREATE TABLE IF NOT EXISTS LOGS (id unique, log)");
  tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "test1")');
  tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "test2")');
});
// 查
db.transaction((tx) => {
  tx.executeSql(
    "SELECT * FROM LOGS",
    [],
    function (tx, results) {
      console.log(results);
      var len = results.rows.length;
      console.log(len);
      console.table(results.rows);
    },
    null
  );
});
// 删
db.transaction(function (tx) {
  tx.executeSql("DELETE FROM LOGS  WHERE id=1");
});
// 改
db.transaction(function (tx) {
  tx.executeSql("UPDATE LOGS SET log='test3' WHERE id=2");
});

3.5.3 Cache

  • Cache Storage
  • Application Cache:应用缓存。可以使用 Application Cache 窗格去查看通过 Application Cache API 创建的资源(即离线资源缓存,如 manifest 缓存清单中的文件)。