使用 Spy-js 对 JavaScript 进行性能分析
Spy-js 是一款用于调试、跟踪和性能分析在不同平台/浏览器/设备上运行的 JavaScript 以及服务端 Node.js 应用程序的工具。 Spy-js 可识别源映射,因此您可以跟踪包含 CoffeeScript 和 TypeScript 代码的应用程序。 有关更多信息,请参阅 调试 CoffeeScript 和 文件监视器。
借助 PyCharm,您可以在特定于 SpyJS 的调试会话期间跟踪您的应用程序,并在专用 UI 中查看结果。
要跟踪脚本,Spy-js 会即时对其进行修改,通过插入插桩指令,在脚本执行时将哪些函数被调用的信息回传到 Spy-js UI。
Spy-js 针对 Web 应用程序和 Node.js 应用程序使用不同的跟踪机制。
要修改网站脚本,Spy-js 必须充当代理服务器,"位于" 您的浏览器与正在跟踪的网站之间。 当您在浏览器中打开被跟踪的网站时,Spy-js 会接收脚本请求,从您的网站请求该脚本,接收脚本后进行必要的修改,再将其发回您的浏览器以执行脚本,并将运行时信息发送到 Spy-js UI。
对于 Node.js 应用程序,如果应用程序已经在运行,Spy-js 无法介入 Node.js 服务器与脚本之间。 因此,要跟踪 Node.js 应用程序,Spy-js 会启动 Node.js 服务器及应用程序本身。 这样,Spy-js 就可以拦截并修改脚本请求和脚本,随后跟踪过程将与跟踪网站脚本时相同地运行。
开始之前
请确保您的计算机上已安装 Node.js。
按照 从 JetBrains 市场安装插件 中的说明,在 设置 | 插件 页面、选项卡 Marketplace 上安装并启用 Spy-js 插件。
Spy-js 用户界面
所有与跟踪相关的活动(例如查看捕获的事件、检查其调用堆栈、导航到源代码等)都在专用的 Spy-js 工具窗口 中进行,尤其是在其 Trace Run 选项卡 中。 该选项卡由一个工具栏和三个窗格组成:
事件窗格
该窗格显示已捕获事件的树。 顶层节点表示参与跟踪的 文档 (即网页)。 当您将鼠标悬停在 文档 上时,PyCharm 会显示一个工具提示,其中包含该 文档 的 URL 地址、打开它的浏览器以及该浏览器运行的操作系统。 该 文档 节点还带有一个图标,用于指示其打开所在的浏览器。
每个 文档 节点下会列出在页面上检测到的事件以及由其启动的脚本。 同类型的事件会被分组到可视容器中。 容器的标题显示其中分组的事件名称、该容器内所有事件的平均执行时间以及事件数量。 您可以展开每个节点并检查其中的各个事件。
脚本文件名具有不同的颜色标识,可帮助您在使用 事件堆栈 窗格时区分它们。 将鼠标悬停在脚本文件名上,您可以看到完整的脚本 URL。
点击事件后,其调用堆栈会显示在 事件堆栈 窗格中。 该堆栈以函数调用树的形式呈现。
事件堆栈窗格
在 事件 窗格中点击某个事件后,其调用堆栈会显示在 事件堆栈 窗格中。 该堆栈以函数调用树的形式呈现。 树中的每个节点表示被调用的函数。 节点文本包含总执行时间、脚本文件名和函数名。 点击节点时, 快速计算 窗格会显示其他函数调用详细信息、参数值和返回值,以及在函数执行期间发生的异常的详细信息(如果有)。
该窗格与编辑器同步,因此您可以从堆栈树中的条目导航到相应的 跟踪文件 或 源文件。
跟踪文件 是脚本的写保护的美化版本,其名称为 <script name>.js.trace 。 当您双击堆栈树中的条目,或选择它并从所选内容的上下文菜单中选择 跳转到跟踪 时,相应的 跟踪文件 会在编辑器中打开,光标定位在所点击的函数处。 另一种方法是按下 自动滚动到跟踪 切换按钮,并选择不同的堆栈节点。 在这种情况下,当您在 事件 窗格中点击事件或脚本时,将打开跟踪文件。
您不仅可以跳转到函数,还可以跳转到其在代码中的调用位置。 为此,选择所需条目,并在上下文菜单中选择 跳转到调用方。
文件内容会被高亮显示,以展示所选堆栈节点的代码执行路径。
当您跟踪包含 ECMASript6、 CoffeeScript 和 TypeScript 代码的应用程序时, Spy-js 还会生成 映射的跟踪文件。 这些是扩展名为 .ts.trace 、 .coffee.trace 或 .js.trace 的 EcmaScript 6、 TypeScript 或 CoffeeScript 跟踪文件。 这些文件中的代码片段会被高亮显示,就好像它们确实被执行过一样。
您还可以在 事件堆栈 窗格中选择某个条目,并从所选内容的上下文菜单中选择 跳转到源代码 ,导航到按原样显示且未美化的 源文件。 如果被跟踪的站点与 一个 PyCharm 项目建立了映射,PyCharm 会根据该映射检测到相应的本地文件,并在编辑器中打开该文件。 如果您跟踪的站点未映射到 一个 PyCharm 项目,PyCharm 会打开只读的 页面源代码 ,就像您在浏览器中选择了 查看页面源代码 一样。
当被跟踪的站点与 一个 PyCharm 项目建立了映射时,在任何尝试编辑已打开的 跟踪文件 的情况下,PyCharm 都会打开 源文件。
快速计算窗格
当您点击 事件堆栈 窗格中的节点时, 快速计算 窗格会显示其他函数调用详细信息、参数值和返回值,以及在函数执行期间发生的异常的详细信息(如果有)。
开始 Spy-js 跟踪会话
在 PyCharm 中,使用类型为 Spy-js 的运行/调试配置来跟踪 Web 应用程序,或使用类型为 Spy-js for Node.js 的运行/调试配置来跟踪 Node.js 应用程序。
创建 Spy-js 调试配置
转到 。 或者,从工具栏上的 运行 小部件中选择 编辑配置。

在打开的 编辑配置 对话框中,点击工具栏上的 添加 按钮(
),并从列表中选择 Spy-js。
将打开 Run/Debug Configuration: Spy-js 对话框。
指定要使用的 Node.js 运行时。
跟踪服务器端口 将自动填写。 为避免端口冲突,建议您接受建议的值,并保持选中 自动配置系统代理 复选框。 因此,将自动为系统代理服务器设置指定的端口号。
或者,手动配置您的系统代理端口。
转到 并打开 使用代理服务器。 在 端口 字段中,键入 跟踪服务器端口 号。
了解更多信息,请参阅 Microsoft 官方网站。
转到 ,点击 高级 ,切换到 代理 选项卡,清除 自动代理配置 ,然后键入您的 Proxy 配置文件的 URL 地址。 请确保 URL 中的端口与运行/调试配置中的 跟踪服务器端口 相同。
了解更多信息,请参阅 Apple 官方网站。
在 使用 列表中,选择配置跟踪会话的方式。
要让 Spy-js 应用其内部预定义配置,请选择 默认配置。
要应用您手动创建的自定义配置,选择 配置文件 选项,然后在下方的 配置 字段中指定您的自定义配置文件的位置。
配置文件 是扩展名为 .js 或 .conf.js 的 JavaScript 文件,其中包含符合 Spy-js 配置要求 的有效 JavaScript 代码。 如果 PyCharm 在项目中检测到扩展名为 .conf.js 的文件,这些文件会显示在列表中。
手动键入配置文件的路径,或点击 浏览
,并在打开的对话框中选择位置。 指定后,配置文件将添加到列表中,这样下次您可以直接从列表中选择,而无需再次指定路径。
开始跟踪 Web 应用程序
在工具栏上的 选择运行/调试配置 列表中选择 新创建的配置 ,然后点击
。 将打开 Spy-js 工具窗口 ,其中包含一个空的 跟踪运行 选项卡和一个用于告知代理服务器状态的 跟踪代理服务器 选项卡。
切换到浏览器并刷新要开始调试的页面。 Spy-js 会开始捕获此页面上的事件, Spy-js 工具窗口会在 事件 窗格中显示它们。
创建 Spy-js for Node.js 调试配置
转到 。 或者,从工具栏上的 运行 小部件中选择 编辑配置。

在打开的 编辑配置 对话框中,点击工具栏上的 添加 按钮(
),并从列表中选择 用于 Node.js 的 Spy-js。
指定要使用的 Node.js 运行时。
如果您选择 项目 别名,PyCharm 将自动使用 JavaScript 运行时 页面上 Node 运行时 字段中的项目默认解释器。 在大多数情况下,PyCharm 会检测到项目默认运行时,并自动填写该字段。
您也可以选择其他已配置的本地或远程解释器,或点击
并配置新的解释器。
指定用于启动应用程序的 JavaScript 文件。
如果您要跟踪 CoffeeScript,请指定生成的 JavaScript 文件的路径。 该文件可以通过外部生成,或通过使用 File Watchers 编译生成。 有关更多信息,请参阅 调试 CoffeeScript。
跟踪服务器端口 将自动填写。 为避免端口冲突,建议您接受建议的值,并保持选中 自动配置系统代理 复选框。 因此,将自动为系统代理服务器设置指定的端口号。
或者,手动配置您的系统代理端口。
转到 并打开 使用代理服务器。 在 端口 字段中,键入 跟踪服务器端口 号。
了解更多信息,请参阅 Microsoft 官方网站。
转到 ,点击 高级 ,切换到 代理 选项卡,清除 自动代理配置 ,然后键入您的 Proxy 配置文件的 URL 地址。 请确保 URL 中的端口与运行/调试配置中的 跟踪服务器端口 相同。
了解更多信息,请参阅 Apple 官方网站。
指定包含要应用到跟踪会话的配置设置的配置文件。
配置文件 是扩展名为 .js 或 .conf.js 的 JavaScript 文件,其中包含符合 Spy-js 配置要求 的有效 JavaScript 代码。 如果 PyCharm 在项目中检测到扩展名为 .conf.js 的文件,这些文件会显示在列表中。
手动键入配置文件的路径,或点击 浏览
,并在打开的对话框中选择位置。 指定后,配置文件将添加到列表中,这样下次您可以直接从列表中选择,而无需再次指定路径。
可选:
键入 Node 参数 以自定义 Node.js 的启动。
例如,要启用跟踪 ECMAScript 6 脚本,请将
--harmony指定为 Node 参数。 请注意,Node.js 必须为 0.11.13 或更高版本。选择应用程序的 工作目录。
默认情况下,该字段显示 项目根文件夹。
指定要在启动时通过 process.argv 数组传递给应用程序的 Node.js 特定参数。
如适用,指定 Node.js 可执行文件的 环境变量。 有关更多信息,请参阅 运行/调试配置:适用于 Node.js 的 Spy-js。
开始跟踪 Node.js 应用程序
在工具栏上的 选择运行/调试配置 列表中选择 新创建的配置 ,然后点击
。 将打开 Spy-js 工具窗口 ,在 跟踪运行 选项卡中显示捕获的事件。
保存和加载跟踪会话
Spy-js 会将跟踪会话的调用和属性存储在 .json 文件中,这些文件可以压缩为 zip 存档。 您可以随时解压它们,将跟踪会话映像加载到 Spy-js 中。 请注意,加载的映像不会还原会话,因为实际上未执行任何脚本。 您只能分析先前已执行代码的流程和属性。
保存跟踪会话的映像
点击
在 事件 工具栏上,然后从列表中选择 保存跟踪。 PyCharm 会将所有受影响的 .json 文件压缩到一个 zip 存档中,并打开保存该存档的文件夹。
加载先前跟踪会话的映像
要激活 Spy-js,请启动与映像中保存的会话相同类型的跟踪会话,分别为 Spy-js 或 Spy-js for Node.js;请参阅上文 开始 Spy-js 跟踪会话。
点击 事件 工具栏上的
按钮,然后从列表中选择 加载跟踪。
在打开的对话框中,选择包含所需会话映像的 zip 存档的位置。 Spy-js 会停止正在运行的会话,并在名为 已加载 <loaded session> 的新选项卡中显示已加载的跟踪。
配置事件捕获策略
默认情况下,Spy-js 会捕获所有已打开 Web 页面上的所有事件,但不包括 https secure 网站,除非您在运行配置中显式指定其 URL 地址。 所有捕获的事件都会显示在 Spy-js 工具窗口的 事件 窗格中。 您可以通过应用用户定义的事件过滤器来抑制对某些类型事件的捕获。
您可以即时定义新的自定义过滤器,或将事件模式添加到现有过滤器。
查看可用的已配置过滤器
点击工具栏上的
。 当前应用的过滤器会以勾选标记标出。 默认情况下,将应用预定义的 捕获全部 过滤器。
在不停止应用程序的情况下停止捕获事件
点击工具栏上的 捕获事件 按钮
,然后从上下文菜单中选择 全部静默。 应用程序仍在运行,但 事件 窗格显示最后一个捕获的事件。 如果您想分析某个脚本,因此需要它显示在 事件 窗格中,而不因捕获到新事件而被移除,这将非常有用。
定义新的事件过滤器
点击工具栏上的 捕获事件 按钮
,然后从列表中选择 编辑捕获排除项。
在打开的 Spy-js Capture Exclusions Dialog 中,点击左侧窗格中的 添加
。
在右侧窗格中,在 排除项名称 字段中指定过滤器名称,并配置排除规则列表。
要添加规则,点击
, 向排除项添加条件 对话框将打开。 在 值/模式 字段中键入模式,在 条件类型 列表中指定该模式应应用于事件类型还是脚本名称。 请注意,使用了 glob 模式匹配。 当您点击 确定 ,PyCharm 会将您带到 Spy-js 捕获排除项对话框。
要编辑规则,请在列表中选择该规则,点击
,并在打开的对话框中更新该规则。 要移除规则,请在列表中选择该规则,并点击
。
选择要应用的过滤器
点击
,并在列表中选中所需过滤器旁边的复选框。 如果尚未配置任何过滤器,或可用过滤器均不适用于该任务,请按照上述说明创建一个新过滤器。
在 事件 窗格中浏览已捕获事件的树时,您可能会遇到一些确定不想跟踪的事件或脚本。 您可以按照上述说明创建过滤器,但在这种情况下,您将不得不离开该窗格。 借助 PyCharm,您可以基于任何事件或脚本创建排除规则,一旦您检测到此类事件或脚本,即可直接在 事件 窗格中创建。
即时创建排除规则
选择要排除的事件,然后选择 静默 <event name> 事件 或 静默 <script name> 文件。 如果当前应用了用户定义的过滤器,新规则会静默添加到其中。 如果 捕获全部 当前处于活动状态,将会打开 Spy-js Capture Exclusions Dialog ,在其中,您可以基于所选事件或脚本创建新过滤器,或选择现有过滤器并将新规则添加到其中。
时间戳标签可帮助您在特定时间段内分析代码的执行情况。 例如,您可以设置两个时间戳标签,并查看在它们之间捕获了哪些事件。 或者,相反,您可以定位在特定时间段内未被捕获但您预期会被捕获的事件,从而发现性能问题。
设置时间戳标签
从 事件 窗格的上下文菜单中选择 添加标签。 在文档节点下会添加一个标记于 <timestamp> 的标签。
在各个窗格与编辑器之间导航
事件堆栈 窗格与 事件 窗格以及编辑器同步。
查看脚本或事件的调用堆栈
在 事件 窗格中点击事件或脚本。 其调用堆栈会显示在 事件堆栈 窗格中。
可选:要在编辑器中自动打开相应的跟踪文件,请按下工具栏上的 自动滚动到跟踪 切换按钮。
在编辑器中打开事件或脚本的跟踪文件
跟踪文件 是脚本的写保护的美化版本,其名称为 <script name>.js.trace 。
在 事件堆栈 窗格中,双击脚本或事件,或在其上下文菜单中选择 跳转到跟踪。
启用自动导航 (点击 自动滚动到跟踪 ),然后在 事件 窗格中点击所需的事件或脚本。
将事件窗格与编辑器直接同步
按下工具栏上的 自动滚动到跟踪 切换按钮。
之后,当您点击 事件 窗格中的节点时,PyCharm 会在 事件堆栈 窗格中显示其调用堆栈,并在编辑器中打开相应的跟踪文件。 此外,当您滚动浏览 事件堆栈 时,PyCharm 会在编辑器中自动打开相应的文件,并高亮显示被调用的函数。
从函数导航到其调用处
在 事件堆栈 窗格中,选择调用堆栈中的所需条目,并从所选内容的上下文菜单中选择 跳转到调用方。
在 ECMAScript 6、TypeScript 或 CoffeeScript 中导航
Spy-js 支持 源映射 ,这意味着您现在可以直接从 事件堆栈 窗格跳转到 ECMAScript 6、 TypeScript 或 CoffeeScript 的原始源代码,并查看哪些代码片段被执行。
Spy-js 还会生成 映射的跟踪文件。 这些是扩展名为 .ts.trace 、 .coffee.trace 或 .js.trace 的 EcmaScript 6、 TypeScript 或 CoffeeScript 跟踪文件。 这些文件中的代码片段会被高亮显示,就好像它们确实被执行过一样。
或者,您可以导航到已执行的 JavaScript 代码,方法是选择 跳转到跟踪。
配置源映射的处理
在 事件 堆栈的工具栏上点击
,并从上下文菜单中选择以下选项,配置源映射的处理方式:
选择 启用源映射查找 ,以使用在编译期间生成的源映射启用到 ECMAScript 6、 TypeScript 或 CoffeeScript 源代码的导航。
选择 启用源映射生成 ,为所有内容生成源映射,以映射已插桩的代码。 如果您打算在 Chrome Dev Tools 或 FireFox FireBug 开发工具中调试原始源代码,请选择此选项。
选择 如可用,始终打开源映射的跟踪 ,以便当您从事件导航到其调用方时, Spy-js 尝试打开 映射的跟踪文件。
从函数调用导航到其源代码
在 事件堆栈 窗格中,选择函数,并从所选内容的上下文菜单中选择以下选项:
要导航到 ECMAScript 6、TypeScript 或 CoffeeScript 源代码,请从所选内容的上下文菜单中选择 跳转到源代码。
要导航到 JavaScript 跟踪文件,请选择 跳转到跟踪。
要导航到映射的跟踪文件(ECMAScript 6、TypeScript 或 CoffeeScript),请选择 跳转到映射的跟踪。
从函数导航到其调用处
在 事件堆栈 中选择函数,并选择 跳转到调用方。
如果已选择 如可用,始终打开源映射的跟踪 选项,将打开相应的映射的跟踪文件。
如果未选择 如可用,始终打开源映射的跟踪 选项,将打开 JavaScript 跟踪文件。
高级跟踪导航
借助高级跟踪导航,您可以基于调用在整个堆栈中移动,并定位未被调用的函数,即定位未被执行的代码片段,并分析其被跳过的原因。
以下六个操作可用:在跟踪文件中,移动到下一个、当前或上一个函数的下一次或上一次调用。 完整的操作列表可在 事件堆栈 窗格的上下文菜单中查看。 在 事件堆栈 窗格的导航工具栏中,也可执行以下操作:移动到所选函数的下一次和上一次调用、移动到上一个函数的上一次调用,以及移动到下一个函数的下一次调用。

当您选择其中一个操作时,光标会跳转到堆栈中的调用处。 如果按下 自动滚动到跟踪 切换按钮,将自动打开相应的跟踪文件,光标定位在该调用处。
高级跟踪搜索
高级跟踪搜索使您能够在整个跟踪(跨所有已跟踪事件)中在某个函数的各次调用之间进行导航。 这意味着,如果您在浏览器中跟踪 5 个页面,且 事件 窗格相应地显示 5 个文档节点,PyCharm 会在所有这些节点下搜索所选函数的调用,并在状态栏中显示找到的该函数的调用次数。
当您调用另一次高级跟踪搜索或导航时,搜索结果会重置,搜索工具栏会隐藏。
另请注意,调用次数会在您选择 在所有事件中搜索对此函数的调用 选项时计算。 在您分析已检测到的调用时,随着时间的推移,会捕获到新的事件,而第一个检测到的调用可能已经从堆栈中移除,这意味着它不再可用于导航。
在所有文档节点中搜索函数的调用
在 事件堆栈 窗格中,选择函数,并从所选内容的上下文菜单中选择 在所有事件中搜索对此函数的调用。
找到的调用次数显示在状态栏中,工具栏会显示四个此前隐藏的山形导航按钮。

在找到的调用之间进行导航
使用山形导航按钮:
要跳转到首次检测到的调用,请点击
。要跳转到最后检测到的调用,请点击
。要跳转到下一个检测到的调用,请点击
状态栏会显示一条消息: 第 <number> 次,共 <total number of detected calls> 次
要跳转到上一个检测到的调用,请点击
。
使用运行时数据扩展基本补全列表(Spy-js 自动补全)
术语 Spy-js 自动补全 指使用从运行时数据检索的建议来扩展 基本补全列表。 Spy-js 自动补全 功能适用于 源文件 中已执行的代码(在相应的 跟踪 文件中以绿色高亮显示)。
当您在源文件中将光标置于某个符号处并按下 Ctrl+Space, Spy-js 会从浏览器或正在运行的 Node.js 应用程序检索数据,并根据以下规则将其与基本补全列表合并:
如果某个对象既出现在基本补全列表中,又从运行时检索到,则提供更多关于参数、属性及其类型等信息的候选项 将保留在列表中。
启用 Spy-js 自动补全
在 事件 工具栏上,点击
按钮,然后从列表中选择 启用 Spy-js 自动完成和放大镜。
在不运行调试会话的情况下求值表达式(Spy-js 放大)
术语 Spy-js 放大 指在不运行调试会话的情况下 求值表达式。 当您点击表达式或将光标置于其上并按下 Ctrl+Alt+F8 时,会在表达式下方显示一个工具提示,显示该表达式的值。 如果 Spy-js 检索到多个值,在工具提示中点击 图标以展开值列表。
放大 功能适用于 源 文件中的已执行和尚未执行的代码。
默认情况下,功能被关闭。
启用 Spy-js 放大
在 事件 工具栏上,点击
按钮,然后从列表中选择 启用 Spy-js 自动完成和放大镜。
查看依赖关系图
借助 Spy-js,您可以为客户端和 Node.js 应用程序构建并检查运行时应用程序/事件图。
生成图:
要构建整个应用程序内的依赖关系图,请选择文档节点,并从所选内容的上下文菜单中选择 显示应用程序依赖关系图。
要构建单个事件的依赖关系图,请在 事件 窗格中选择所需事件,并从所选内容的上下文菜单中选择 显示事件依赖关系图。
分析图:
该图会在单独的编辑器选项卡中打开。 图中的节点表示您的项目文件,而边表示源文件中有一个或多个函数会调用目标文件中的函数。
要检查节点或边的详细信息,请选择该节点或边,并在编辑器右上角的专用窗格中查看其 详细信息 树。 该窗格会显示连接的函数组合,以及调用所在的事件和调用次数。