前端开发调试之 PC 端调试
这是我参与第五届青训营伴学笔记创作活动的第 4 天,记录了对于前端 PC 端调试的技巧。
一、前端Debug的特点
- 多平台:浏览器、Hybrid、NodeJs、小程序、桌面应用等
- 多环境:本地开发环境、线上环境
- 多工具:Chrome devTools、Charles、Spy-Debugger、Whistle、vConsole……
- 多技巧:Console、BreakPoint、sourceMap、代理等。
二、Chrome DevTools
浏览器右键,点击检查
1. Element
左边显示元素结构,右边是样式
- 点击.cls开启动态修改元素的class
- 输入字符串可以动态地给元素添加类名
- 勾选/取消类名可以动态的查看类名生效效果
- 点击具体的样式值(字号、颜色、宽度高度等)可以进行编辑,浏览器内容区域实时预览
- Computed下点击样式里的箭头可以跳转到styles面板中的css规则
可以用以下2种方式强制激活伪类:
- 选中具有伪类的元素,点击:hov
- DOM树右键菜单,选择Force State
可以右键DOM节点,点击Capture node screenshot,截取当前节点的效果图
2. Console控制台
用来展示日志,有很多种
-
console.log:打印一条日志
-
console.warn:打印警告,黄色
-
console.error:打印错误信息,红色
-
console.debug:打印调试信息
-
console.info:console.log 别名,输出信息
-
console.table:具象化的展示JSON和数组数据
-
console.dir:通过类似文件树的方式展示对象的属性
-
console.time()和console.timeEnd():分别放在js脚本的前面和后面,测量js脚本的消耗时间
- 可以传人一个参数,作为计时器的名称
-
占位符:给日志添加样式,可以突出1重要的信息
-
%s:字符串占位符
-
%o:对象占位符
-
%c:样式占位符
-
%d:数字占位符
-
例:
-
console.log('%s %o %c,%d', 'demo', { age: 18}, 'font-size: 20px; color: blue', 5);
不同类型的值输出的颜色是不一样的
console.log(123);
console.log('123');
var arr = [
{
name: 'Tom',
age : 18
},
{
name: 'Cat',
age : 20
}
]
console.log(arr); // [{...},{...}]
console.table(arr);
3. Source Tab
展示项目的源代码
3-1 Break Point与Watch
在js中加入debugger;
或者在Source面板点击代码的行号,代码在运行时如果用到此处js代码就会在此断点处停止运行,等待进一步指示,这时就用到了上图中的区域3Debug工具栏,自行决定如何处理程序。
- 在代码调试时,把鼠标移动到要观测的变量上,会自动显示该值。
- Watch栏也会观测变量的值。也支持自行输入查询变量
- Breakpoints:展示程序中的断点
3-2 Scope(作用域)与Call stack(调用栈)
- 展开Scope可以查看作用域列表(包含闭包)
- 展开Call Stack可以查看当前javaScript代码的调用栈
3-3 其他
XHR/fetch Breakpoints:所有请求的断点,一旦程序发生了网络请求,就可以进入断点
DOM breakpoints:HTML中的某个元素发生变化的时候,可以添加断点
其余的不太常用
3-4 压缩后的代码如何调试?
由于前端代码天生具有"开源"属性,出于安全考虑,上线之前JavaScript代码通常会被压缩,压缩后的代码只有一行,变量使用'a'、'b'等替换,整体变得不可阅读。那么压缩后的代码如何调试呢?
使用Source Map
就可以帮助我们找到源码了,Source map就是一个信息文件,里面储存着位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。代码报错时,直接点击报错链接即可跳转到源码。
在webpack打包的时候加上这样一句:**devtool: 'source-map',**就可以使用source map了
下面是一个打包后的map文件,肯定比源码大。
- mappings字段存储了源文件和Source Map的映射
- 英文,表示源码及压缩代码的位置关联
- 逗号,分隔一行爱吗中的内容
- 分号,代表换行
那么既然Source Map可以映射源码,那压缩后的代码带上Source Map上线不就又不安全了吗?如果不带Source Map上线,那么出错后又不可调试了,不行。
Source Map通常应用场景是监控,上线时不带Source Map,通常这样解决:
- 打包时带上Source Map
- 上线前将Source Map上传到另一平台,比如监控平台
- 删掉原项目中的Source Map,将不带Source Map的产物部署上线
四、Network
展示站点请求的各种各样的网络资源,Fetch/XHR查看所有的请求
- 区域1:控制面板
- 区域2:过滤面板
- 区域3:概览区域
- 区域4:Request Table面板
- 区域5:总结面板
- 区域6:请求详情面板
有很多小技巧
-
Fast 3G代表快网速环境下
-
Slow 3G代表慢网速环境下
-
Offline代表离线状况下
-
Waterfall查看请求是串行还是并行
- 并行:图中的小图标在同一竖线上,代表同时请求
- 串行:图中小图标在不同竖线上,代表按顺序执行
在前后端交互时,可以通过Preview和Response来查看后端的返回数据,快速发现问题
五、Application
Application面板展示与本地存储相关的信息
- Local Storage
- Session Storage
- IndexedDB
- Web SQL
- Cookie
可以通过左侧Application下的Storage面板中的Clear Site Data清除网页的本地存储数据
六、Performance
点击左上角录制一段时间,就可以看见各项参数了
为了更好理解这个面板,官方给了我们一个demo地址来方便理解:googlechrome.github.io/devtools-sa…
我们没有对原页面进行修改,这个页面非常流畅,main面板也没有爆红。
下面我们进行修改,将CPU降速6倍,并添加多个块:
可以发现页面变得卡顿,我们查看FPS指标,在More tools处点击Rendering
我们发现页面只有30帧,正常的浏览器刷新率至少在60帧及以上,出现了性能问题。重新录制:
main模块爆红,并提示我们耗时过长,我们点击下面的一个小紫块,会发现下方提示我们查看app.js.71,点击查看源码即可发现问题:
app.update = function (timestamp) {
for (var i = 0; i < app.count; i++) {
var m = movers[i];
if (!app.optimize) {
var pos = m.classList.contains('down') ?
m.offsetTop + distance : m.offsetTop - distance;
if (pos < 0) pos = 0;
if (pos > maxHeight) pos = maxHeight;
m.style.top = pos + 'px';
// 这里有问题,用的是offsetTop,导致每次判断都会导致重新渲染
if (m.offsetTop === 0) {
m.classList.remove('up');
m.classList.add('down');
}
if (m.offsetTop === maxHeight) {
m.classList.remove('down');
m.classList.add('up');
}
} else {
// 优化方案,用变量进行存储
var pos = parseInt(m.style.top.slice(0, m.style.top.indexOf('px')));
m.classList.contains('down') ? pos += distance : pos -= distance;
if (pos < 0) pos = 0;
if (pos > maxHeight) pos = maxHeight;
m.style.top = pos + 'px';
if (pos === 0) {
m.classList.remove('up');
m.classList.add('down');
}
if (pos === maxHeight) {
m.classList.remove('down');
m.classList.add('up');
}
}
}
frame = window.requestAnimationFrame(app.update);
}
点击页面中的Optimize,就会发现页面变得不卡顿了,因为采用了下面的方法。
七、Lighthouse
用于查看各种指标以及性能。
我们进行实际测试。
点击右上角的Analyze page load进行解析,以掘金官网为例
- First Contentful Paint:第一个DOM元素开始渲染的时间
- Largest Contentful Paint:全部渲染完的时间
关键的性能指标在第一张图片中已经指出。
八、参考
- 字节录播课 - 前端开发调试之 PC 端调试