w3ctech

关于前端问题的调试

文章参考:The Art of Debugging

大部分情况下,我们都在追求写出没有bug的代码,但是没有bug的代码不代表运行期没有bug,你的代码可能在各种奇怪的浏览器、各种奇怪的设备、各种奇葩的网络下运行,各种改过的内核、时快时慢甚至会突然断掉的网络,还有你都叫不出名字的手机,都可能让你浪费一下午时间却毫无收获。

大部分情况下,快速调试并解决问题的前提就是能够先通过经验快速判断可能的问题来源,这完全就是靠个人经验。特别是一些万金油式的解决方案,以前是zoom:1,现在是transform: translate3d(0, 0, 0)或者-webkit-backface-visibility: hidden

善用框架

基本上所有的网站,都可能依赖了一些外部的库或者模块,而可能这个网站的所有开发者可能都不了解这个库的代码到底有些啥,有时候出了bug,debug到依赖库里时,基本就无解了。

所以基本上,如果要将外部模块放到项目工程中使用,了解模块代码及原理应当是对工程师一个基本要求,特别是类似react这类重度依赖build的框架,很多复杂问题都需要从build后的代码查起,或者,排除法也是一个比较快速的定位问题方式。

当然,这类工具都提供了对应的debug工具,比如devtools extension to debug your React apps,善用一个库,熟悉配套的调试工具也是必要的技能。

跨浏览器测试

有一些代码是显然不会有浏览器差异的,比如

function magicNumber(a, b) {
  return Math.pow(a, b) * b / Math.PI;
}

但是大部分场景下,你不会幸运到只写这样的代码,使用zuul或者karma来做一轮自动化的浏览器测试,应该会尽早暴露一些兼容性问题。

debug的方式

出现Bug后,一般都有一个固定的步骤

  1. 复现BUG
  2. 找到BUG的原因
  3. 修复BUG

复现

通常复现BUG是一个非常麻烦的事情,大部分情况下,遇到的都是其他人有问题,自己这边缺是好的(不然也不会上线了)。

所以收集出BUG用户的信息就显的异常重要,一般需要收集的有:

  1. 操作系统及浏览器,大部分问题都出在这里,浏览器兼容性什么的
  2. 设备名,部分国产机型实在奇葩,比如中信的某XXX手机,border-radius都不支持。
  3. 网络环境,低网速的情况下,任意请求都可能失败,如果容错能力不足,是极有可能进入异常状态的。
  4. 浏览器设置,常见的有浏览器缩放导致UI布局错乱什么的,还有禁用cookie和javascript的。这些都可以针对性的做一些提醒。
  5. 设备ip,现在代码都部署在全国,某个节点的某台机器文件同步失败,用户访问的是老文件什么的也是非常有可能出现的。
  6. 缓存,上一次出错的代码还是可能被路由器、浏览器等缓存。
  7. 浏览器插件,比如adblock,加了请求白名单什么的,会block一些正常请求的内容。

如果收集到的信息不够复现条件,就只能亲自用出错的设备来debug了,这也是最效率的办法。

有一些Bug是无法复现的,比如缓存相关的,刷新缓存后,也就无法复现了,这类问题可以记录下来,作为后续排查的一个参考。

找到bug

有一些bug非常清晰,打开控制台就很清楚,哪个文件的第几行代码报错了,或者是你的工作经验可以让你快速判断并定位到问题原因。

但是大部分Bug不一定又会有对应的报错,所以我们可能会用到的工具包括:

  1. 代码断点,一行一行看是哪行代码的执行不符合预期
  2. DOM修改断点,看下到底是哪个DOM操作导致页面显示异常
  3. 抓包,fiddler或者charles,看下是哪个请求返回异常
  4. 排除法,这个办法虽然看起来很笨,但是非常有效率,可以解决一些请求或者加载模块导致的问题

找bug还是比较依赖控制台工具的使用,平时还是需要耐心读读工具使用文档的。

有一些浏览器的控制台比较渣,比如IE6/7/8,报错信息也没有详细的描述,那么可以用IE10或者11的控制台,切换到IE7/8的模式,就可以看到详细的报错信息了。也算是一个小技巧了。

解决bug

一般如果刚发布一个版本,就收到bug反馈,最快的解决方案一定是回滚代码,所以每个发布系统一定要有回滚的功能,千万不能通过修改代码来实现回滚,鬼知道改代码的时候是否会有另外一个bug,特别是在紧急状况下,更容易出错。

要实现快速回滚,版本控制就显得非常重要,每一次发布做一次tag操作,可以实现非常精准的回滚操作。

代码回滚之后,就可以慢慢解决问题,然后继续发布了。

如果可以,每一个解决的bug都应当有一个对应的单元测试来保证bug的正确解决,并再以后不再出现。

总结

总之,工程师生涯基本上就是和bug和优化作斗争。希望本文的调试技巧能有所帮助。

w3ctech微信

扫码关注w3ctech微信公众号

共收到0条回复