分析 JavaScript 性能
Visual Studio Code 支持为 JavaScript 程序收集和查看性能配置文件。要开始使用,您首先需要为您的 Node.js 程序 或 浏览器应用程序 配置调试器。
配置文件类型
根据您要优化的内容,您可能需要进行不同类型的分析。
- CPU 分析 - CPU 分析告诉您您的程序在 JavaScript 中花费了多少时间。请记住,虽然您可以等待异步承诺或回调,但一次只能执行一个 JavaScript 表达式。CPU 分析每秒收集大约 10,000 个样本,以告诉您在那一刻是否正在运行哪个表达式。
- 堆分析 - 堆分析告诉您您的程序如何随时间分配内存。分配内存可能很昂贵,减少代码分配的内存量可以提高性能。
- 堆快照 - 堆快照是您程序分配内存的瞬时视图。如果您发现您的程序使用了大量的 RAM 并想找出原因,堆快照可能很有用。请注意,收集堆快照对于更复杂的程序可能需要几分钟,并且当前不支持在内置编辑器中查看堆快照。
收集配置文件
要收集分析,您需要调试您的程序。调试完成后,您可以通过几种方法收集分析
- 使用 **调用堆栈** 视图中的“记录”按钮。这使您可以进行 CPU 分析、堆分析和堆快照。
- 通过在程序中调用
console.profile()
。这将收集 CPU 分析。
使用记录按钮
调试完成后,切换到“运行和调试”视图 (⇧⌘D(Windows、Linux Ctrl+Shift+D)),并找到 **调用堆栈** 视图。将鼠标悬停在您要调试的会话上,然后选择 **获取性能分析** 按钮。您也可以从命令面板 (⇧⌘P(Windows、Linux Ctrl+Shift+P)) 运行此命令。
然后,VS Code 将询问您要进行哪种 性能分析;选择适合您的分析。
最后,VS Code 将询问您何时停止进行分析。您可以选择:
- 手动停止分析之前一直进行分析。
- 设定持续时间进行分析。
- 遇到特定断点时停止分析。
如果您选择了第一个选项,可以通过点击调试工具栏中显示的红色“记录”图标停止分析。收集分析后,分析查看器 将自动打开。
使用 console.profile
您可以使用对 console.profile
的调用手动检测您的代码以启动分析,并使用 console.profileEnd
停止分析。在这两个调用站点之间将收集 CPU 分析。
console.profile();
doSomeVeryExpensiveWork();
console.profileEnd();
生成的 .cpuprofile
将自动保存在您的工作区文件夹中。您可以选择该文件以在内置的 分析查看器 中打开它。
分析配置文件
表格视图
VS Code 具有一个集成的可视化工具,支持查看 JavaScript .cpuprofile
和 .heapprofile
文件。当您打开这些文件之一时,您将首先看到一个类似于下面的表格视图
这是一个程序的 **自下而上** 视图。每行代表程序中的一个函数,默认情况下,它们按在该特定函数中花费的时间排序。这也称为“自身时间”。函数的“总时间”是在该函数及其所有调用函数中花费的时间之和。您可以展开每个表格行以查看该函数是从何处调用的。
例如,考虑以下代码
function a() {
doSomethingFor5Seconds();
b();
}
function b() {
doSomethingFor3Seconds();
}
a();
在这种情况下,a
的自身时间为 5 秒,a
的总时间为 8 秒。b
的自身时间和总时间均为 3 秒。堆分析的操作方式相同,但使用自身大小和总大小来指示在每个函数或其被调用者中分配的内存量。
火焰图
表格视图在某些情况下很好,但通常您可能希望看到分析的更直观的表示。您可以通过点击表格视图右上角的火焰 🔥 图标来实现。如果您尚未安装,系统将提示您安装提供火焰图编辑器的额外扩展。
这可能最初看起来很混乱,但不要担心,我们会弄清楚的!
对于 CPU 分析,横轴是分析的时间线,使您可以查看程序在每个时刻都在做什么。对于堆分析,横轴是程序分配的总内存。
图中的每个条形或“火焰”都是一个调用堆栈。最外层的顶层函数调用(或调用堆栈的“底部”)显示在编辑器的顶部,它调用的函数显示在下方。条形的宽度由其总时间或总内存决定。
您可以点击火焰图中的条目以查看有关它的更多信息,并且可以使用鼠标滚轮放大和缩小。您也可以在图表上的任何位置拖动以在放大时导航。
左重视图
如果您正在使用 CPU 分析,您看到的火焰图很可能不像上面的那样易于理解。您可能有很多看起来像这样的单独调用堆栈
为了更轻松地进行分析,VS Code 分析了“左重”视图,该视图将所有类似的调用堆栈组合在一起。
这将从分析的时间顺序视图切换到更类似于堆分析的视图。横轴仍然是分析的总持续时间,但每个条形表示该函数调用在从该堆栈调用的 **所有** 时间内的总时间。
对于某些应用程序(例如服务器)而言,这种视图更有用,其中单个调用可能相对较快,但您想找出跨多个调用的总成本最高的函数。