相比纯看代码来说,我更推荐结合 debugger 来看,它可以让我们看到代码实际的执行路线,每一个变量的变化。可以大段大段代码跳着看,也可以对某段逻辑一步步的执行来看。
Javascript 代码主要有两个运行环境,一个是 Node.js ,一个是浏览器。一般来说,调试 Node.js 上跑的 JS 代码我会用 VSCode 的 debugger,调试浏览器上的 JS 代码我会用 chrome devtools。直到有一天我发现 VSCode 也能调试浏览器上的的 JS 代码,试了一下,是真的香。
具体有多香呢?我们一起来看一下。
在项目的根目录下有个 .vscode/launch.json 的文件,保存了 VSCode 的调试配置。
我们点击 Add Configuration 按钮添加一个调试 chrome 的配置。
配置是这样的:
url 是网页的地址,我们可以把本地的 dev server 跑起来,然后把地址填在这里。
然后点击 debug 运行:
VSCode 就会起一个 Chrome 浏览器加载该网页,并且在我们的断点处断住。会在左侧面板显示调用栈、作用域的变量等。
最底层当然是 webpack 的入口,我们可以单步调试 webpack 的 runtime 部分。
也可以看下从 render 的流程,比如 ReactDOM.render 到渲染到某个子组件,中间都做了什么。
或者看下某个组件的 hooks 的值是怎么变化的(hooks 的值都存在组件的 fiberNode 的 memerizedState 属性上):
可以看到,调试 webpack runtime 代码,或者调试 React 源码、或者是业务代码,都很方便。
可能你会说,这个在 chrome devtools 里也可以啊,有啥特别的地方么?
确实,chrome devtools 也能做到一样的事情,但 VSCode 来调试网页代码有两个主要的好处:
- 在编辑器里面给代码打断点,还可以边调试边改代码。
- 调试 Node.js 的代码和调试网页的代码用同样的工具,经验可以复用,体验也一致。
对于第一点,chrome devtools 的 sources 其实也可以修改代码然后保存,但是毕竟不是专门的编辑器,用它来写代码比较别扭。我个人是比较习惯边 debug 边改代码的,这点 VSCode 胜出。
调试 Node.js 我们一般用 VSCode,而调试网页也可以用 VSCode,那么只要用熟了一个工具就行了,不用再去学 chrome devtools 怎么用,而且用 VSCode 调试体验也更好,毕竟是我们每天都用的编辑器,更顺手,这点也是 VSCode 胜出。
但你可能说那我想看 profile 信息呢?也就是每个函数的耗时,这对于分析代码性能很重要。
这点 VSCode debugger 也支持了:
点击左侧的按钮,就可以录制一段时间内的耗时信息,可以手动停止、可以指定固定的时间、可以指定到某个断点,这样 3 种方式来选择某一段代码的执行过程记录 profile 信息。
它会在项目根目录保存一个 xxx.cpuprofile 的文件,里面记录了执行每一个函数的耗时,可以层层分析某段代码的耗时,来定位问题从而优化性能。
如果装了 vscode-js-profile-flame 的 VSCode extension 后,还可以换成火焰图的展示。
有的同学可能看不懂火焰图,我来讲一下:
我们知道某个函数的执行路径是有 call stack 的,可以看到从哪个函数一步步调用过来的,是一条线。
但其实这个函数调用的函数并不只一个,可能是多个:
调用栈只是保存了执行到某个函数的一条路线,而火焰图则保存了所有的执行路线。
所以你会在火焰图中看到这样的分叉:
其实就是这样的执行过程:
来算一道题:
函数 A 总耗时 50 ms,它调用的函数 B 耗时 10 ms,它调用的函数 C 耗时 20 ms,问:函数 A 的其余逻辑耗时多少 ms?
很明显可以算出是 50 - 10 - 20= 20 ms,可能你觉得函数 D 耗时太长了,那就去看下具体代码,然后看看是不是可以优化,之后再看下耗时。
就这么简单,profile 的性能分析就是这么做的,简单的加减法。
火焰图中的每个方块的宽度也反应了耗时,所以更直观一些。
JS 引擎是 event loop 的方式不断执行 JS 代码,因为火焰图是反应所有的代码的执行时间,所以会看到每一个 event loop 的代码执行,具体耗时多少。
每个长条的宽度代表了每个 loop 的耗时,那当然是越细越好,这样就不会阻塞渲染了。所以性能优化目标就是让火焰图变成一个个小细条,不能粗了。
绕回正题,VSCode 的 cpu profile 和火焰图相比 chrome devtools 的 performance 其实更简洁易用,可以满足大多数的需求。
我觉得,除非你想看 rendering、memory 这些信息,因为 VSCode 没有支持需要用 chrome devtools 以外,调试 JS 代码,看 profile 信息和火焰图,用 VSCode 足够了。
反正我觉得 VSCode 调试网页的 JS 代码挺香的,你觉得呢?