Bug与Debug
Bug的产生
前端Debug的特点
- 多平台:浏览器、Hybrid、NodeJs、小程序、桌面应用.....
- 多环境:本地开发环境、线上环境
- 多工具:Chrome devTools、Charles、Spy-Debugger、Whistle、vConsole...
- 多技巧:Console、BreakPoint、SourceMap、代理.....
Chrome DevTools
Element区:动态修改元素和样式
- 点击.cls开启动态修改元素的class
- 输入字符串可以动态的给元素添加类名
- 勾选/取消类名可以动态的查看类名生效效果
- 点击具体的样式值(字号、颜色、宽度高度等)可以进行编辑,浏览器内容区域实时预览
- Computed下点击样式里的箭头可以跳转到styles面板中的CSS规则
- 选定前
- 选定后
添加新类后可以使用用其他CSS类
动态修改样式(包括颜色大小等各种CSS样式):
那如果有要修改伪类(如覆盖、点击等)的需求呢?
可以用以下2种方式强制激活伪类
- 选中具有伪类的元素,点击:hov
- DOM树右键菜单,选择Force State
如何快速找到要调试的样式?
点击light dark左侧箭头,我们就跳转到了CSS文件的来源,在这里,我们就可以修改对应组件的样式
Console区:日志面板
-
console.log -
console.warn -
console.error -
console.debug -
console.info -
console.table具象化地展示JSON和数组数据
-
console.dir以文件树方式展示对象中的属性和对应的值
首先标记好一个对象,这里我们给该对象加上
id="111"的标记然后,使用
console.log尝试获取box1的属性,未果尝试使用
console.dir,成功获取box1的全部属性 -
占位符
给日志添加样式,可以突出重要的信息
%s:字符占位符 %o:对象占位符 %c:样式占位符 %d;数字占位符
Source Tab区:
-
区域1:页面资源文件目录树(源代码)
-
区域2:代码预览区域
-
区域3:Debug 工具栏
从左到右依次为
- 暂停(继续)
- 单步跳过
- 进入函数
- 跳出函数
- 单步执行
- 激活(关闭) 所有断点代码执行异常处自动
-
区域4:断点调试器
断点调试界面
-
使用关键字 debugger 或 代码预览区域的行号可以设置断点
-
执行到断点处时代码暂停执行
-
展开 Breakpoints 列表可以查看断点列表,勾选/取消可以激活/禁用对应断点
-
暂停状态下,鼠标 hover 变量可以查看变量的值
-
在调试器 Watch 右侧点击 + 可以添加对变量的监控,查看该变量的值
作用域与调用栈
XHR/提取断点
当设置XHR/fetch断点后,当网页中发起XMLHttpRequest或fetch请求时,请求会在达到断点时暂停执行,让你有机会检查请求的细节、请求参数、响应数据等,并进行调试操作。
DOM断点
DOM断点(DOM breakpoints)用于调试和捕获网页中的DOM操作。
DOM断点允许你在网页中的DOM元素上设置断点,当相关的DOM操作发生时,代码会在达到断点时暂停执行,以便你进行调试操作和查看相关的DOM状态。
压缩后的代码如何调记?
前端代码天生具有“开源”属性,出于安全考虑,JavaScript代码通常会被压缩,压缩后的代码只有一行,变量使用'a'、'b'等替换,整体变得不可阅读。那么压缩后的代码如何调试呢?
Source Map
mappings 字段存储了源文件和 Source Map 的映射
- 英文,表示源码及压缩代码的位置关联
- 逗号,分隔一行代码中的内容
- 分号,代表换行
既然 Source Map 可以映射源码,那压缩后的代码带上 Source Map 上线不就又不安全了吗?
一般建议在将代码部署到生产环境之前,将 Source Map 文件从压缩后的代码中移除或者禁用 Source Map 功能。这样可以防止攻击者获取到源代码的详细信息。
同时,还有其他一些安全措施可以采取,例如在生产环境中使用代码混淆(code obfuscation)来增加代码的复杂性和可读性,以降低攻击者分析源代码的难度。
NetWork区
Network面板里面可以看到所有的网络请求信息,进行抓包操作,禁止从cache中加载资源,限制带宽模拟弱网环境等等。选中一项网络请求信息,可以查看该请求的详细信息,比如请求行、请求头、响应行、响应头和响应体等等。直观地看到数据包中的原始内容,从而排除是否是自己网页渲染出了bug。
- 区域1:控制面板
- 区域2:过滤面板
- 区域3:概览区域
- 区域4:Request Table 面板
- 区域5:总结面板
- 区域6:请求详情面板
tips:
Applications区
Application 应用面板,主要用来查看本地的一些缓存数据,比如 Storage、Cookie、离线缓存、本地数据库等。
Performance区
Performance 面板,主要用来检测性能问题。平时开发应该很少用到,但遇到页面性能提升瓶颈时,这是个很好的利器,帮助我们快速排查定位出引起性能问题的原因。我们先来看看该面板几个区域的主要功能:
-
区域1:控制面板
-
区域2:概览面板
- FPS:每秒帧数
- CPU:处理各个任务花费的时间
- NET:各个请求花费时间
-
区域3: 线程面板
- Frames:帧线程
- Main:主线程,负责执行Javascript,解析HTML/CSS,完成绘制
- Raster:Raster线程,负责完成某个layer或者某些块(tile)的绘制。
-
区域4: 统计面板
Performance 运用:
页面卡顿——>查看FPS指标——>寻找性能瓶颈——>优化代码
这里采取另一种方式,如图,选择渲染
在这里,我们发现,这个网页正在丢帧!
我们选择Main区
重新录制,发现了很多红色的区域
右上角有红色小三角的地方,示意此处有性能瓶颈
现在选中下方紫色区域,发现是此区域导致性能瓶颈
Lighthouse区
用于评估网页或Web应用的质量和性能,且提供一系列的审查和建议
核心Web指标
- Largest Contentful Paint (LCP):最大内容绘制,测量加载性能。为了提供良好的用户体验,LCP 应在页面首次开始加载后的2.5 秒内发生。
- First Input Delay (FID):首次输入延迟测量交互性。为了提供良好的用户体验,页面的 FID 应为100毫秒或更短。
- Cumulative Layout Shift (CLS):累积布局偏移,测量视觉稳定性。为了提供良好的用户体验,页面的 CLS 应保持在 0.1.或更少。
移动端H5调试
真机调试
iOS
- 使用 Lightning 数据线将 iPhone 与 Mac 相连
- iPhone 开启 Web 检查器(设置 -> Safari -> 高级 -> 开启 Web 检查器)
- iPhone 使用 Safari 浏览器打开要调试的页面
- Mac 打开 Safari 浏览器调试(菜单栏 —> 开发 -> iPhone 设备名 -> 选择调试页面)
- 在弹出的 Safari Developer Tools 中调试
没有 iPhone 设备可以在 Mac App Store 安装 Xcode 使用其内置的 iOS 模拟器
Android
- 使用 USB 数据线将手机与电脑相连
- 手机进入开发者模式,勾选 USB 调试,并允许调试
- 电脑打开 Chrome 浏览器,在地址栏输入:chrome://inspect/#devices 并勾选 Discover USB devices 选项
- 手机允许远程调试,并访问调试页面
- 电脑点击 inspect 按钮
- 进入调试界面
直接使用手机扫码查看,体验更佳
Vconsole
- 日志(Logs):console.log | info | error |...
- 网络(Network):XMLHttpRequest,Fetch, sendBeacon
- 节点(Element): HTML节点树
- 存储(Storage): Cookies,LocalStorage,SessionStorage
- 手动执行 JS 命令行
- 自定义插件
使用代理工具调试
原理
- 电脑作为代理服务器
- 手机通过HITP代理连接到电脑
- 手机上的请求都经过代理服务器
常用工具
以 Charles 为例
- 安装 Charles
- 查看电脑 IP 和 端口
- 将 IP、端口号填入手机 HTTP 代理
- Charles 允许授权(默认情况下,Charles 无法抓取https的请求,需要安装证书)
- 使用 SwitchHosts!软件给 Mac 电脑配 Hosts
- 手机访问开发环境页面
Nodejs调试
Inspector Protocol + Chrome Devtool
-
执行命令
node --inspect=8888 index.js -
chrome 浏览器访问服务
-
点击绿色 node 图标打开 node 调试面板 (在chrome://inspect/#devices 中配置network target)
-
在 node 调试面板中使用断点调试
Inspector Protocol + VS Code
- VS Code 点击运行
- 添加配置
- 启动调试
- 添加断点
- 查看变量、堆栈
常用调试技巧
线上即时修改Overrides
我们平时在 Source 面板在线修改调试代码,会实时更新效果,但浏览器一刷新之前修改的全部恢复原样,这样子调试代码效率就很低,只能浏览器调试改点,代码跟着改点很麻烦。为了解决这个问题,我们可以使用 Overrides 保存线上修改后的文件,并能清晰看出改动了哪些地方,最后修改代码也方便。
Overrides 使用步骤如下:
- 打开 Sources 面板下的的 Overrides。
- 点击 Select folders for Overrides。选择一个本地的空文件夹目录。
- 允许授权
- 在 page 中修改代码,修改完成后 command + s 保存。
- 打开 devTools ,点击右上角的三个小 点 -> More tools -> Changes,然后就 能看到所有修改了。
利用代理解决开发阶段的跨域问题
启用本地 source map
线上环境的代码是打包压缩的,且没有 source map 文件,排查定位问题不方便,这时可以使用 Charles,配置 Map Local,将线上环境代理到本地,运行本地文件,本地有 source map就能快速定位到问题啦。
线上不存在 Source Map时可以使用Map Local网络映射功能来访问本地的 Source Map文件。
使用代理mock数据
- 右键选中要mock数据的接口,选择save response,保存文件到本地
- 本地打开保存的文件,编辑想mock的数据并保存
- 右键选中第一步的接口,选择Map Local,Local Path选择第二步的文件