脚本性能分析器 是 开发者控制台 中的一个工具,允许您记录所有正在运行的脚本的性能分析会话,并查看它们的 CPU 时间成本,具有自定义记录和显示设置。它可以记录所有类型的函数调用,包括 Luau 函数、方法调用和属性访问。此工具有助于识别占用最多 CPU 资源并降低性能的脚本。
记录性能分析会话
在记录之前,您需要从以下选项中选择记录环境:
您还可以设置以下记录选项:
| 行为 | 选项 | 默认 | 描述 |
|---|---|---|---|
| 频率 | 每秒 1000 次 (1 KHz) 每秒 10,000 次 (10 KHz) | 1 KHz | 10 KHz 的频率具有更高的精度,因为脚本性能分析器可能无法捕捉到比您所选频率更频繁执行的 API 调用,但它也具有更高的性能成本。 |
| 会话长度 | 1 分钟 5 分钟 10 分钟 手动 | 手动 | 手动选项需要您手动停止记录。 |
| 实时轮询行为 | 开启 关闭 | 关闭 | 此行为在性能分析会话期间每秒轮询和刷新分析数据。 |
要记录新的性能分析会话:
打开 开发者控制台。
扩展工具下拉菜单以选择 ScriptProfiler。

扩展客户端-服务器下拉菜单以选择 客户端 或 服务器。

(可选)勾选 实时 复选框以启用实时轮询行为。
(可选)选择 频率 和 时间 以选择记录频率和会话时间长度,如果您不想使用默认值。
点击 开始 以开始性能分析会话。如果您设置了持续时间,脚本性能分析器会在会话中显示倒计时计时器。
点击 停止 或等待录制完成以显示性能分析数据。
阅读性能分析数据
会话停止后,脚本性能分析器会生成一个表,显示每个函数调用在 CPU 时间上花费了多少时间。该表按耗时从多到少排序函数调用,并允许您通过名称搜索特定函数。它提供以下两种视图:
- 调用图 (默认): 基于帧任务对函数调用进行分类并以树结构显示。这种视图将每个任务类别显示为同一根节点下的节点,并允许您展开以查看函数。您还可以悬停在树中的任何节点上,以查看文件和行信息。例如,Stepped/CameraInput/<anonymous> 可能会显示 Players.[LocalPlayer].PlayerScripts.PlayerModule.CameraModule.CameraInput:125。

- 函数: 列出所有函数,而不按任务对其进行分类。

您还可以选择以下显示选项以满足调试需求:
| 名称 | 选项 | 默认 | 描述 |
|---|---|---|---|
| 单位 | 毫秒 (ms) 百分比 (%) | ms | 以毫秒或总记录会话的百分比显示每个 API 调用花费的时间。 |
| 平均 | 关闭 1 秒 1 分钟 5 分钟 10 分钟 | 关闭 | 根据所选值计算每个 API 调用的平均花费时间。如果您选择的选项长于会话长度,脚本性能分析器会根据会话长度推断平均值。例如,您可以为 1 分钟的会话选择 5 分钟选项,以查看如果代码运行 5 分钟的预期平均值。 |
导出性能分析数据
脚本性能分析器允许您将记录的性能分析数据导出为 JSON 文件。要在性能分析会话后导出记录的数据:
在脚本性能分析器窗口中,点击 导出。
在导出窗口中,选择您想要导出的性能分析会话。 如果您想设置自定义名称,请重命名默认文件名。
点击 导出 保存 JSON 文件。

导出的 JSON 文件包含以下字段:
- 版本: 版本号。
- SessionStartTime: 记录会话开始时间的毫秒时间戳。
- SessionEndTime: 记录会话结束时间的毫秒时间戳。
- 类别: 在性能分析会话中记录的帧任务类别的数组。每个条目包括:
- 名称: 每个帧任务类别的名称。
- NodeId: 任务类别 (节点) 的唯一标识符。它是 Nodes 数组中的 1 基索引。例如,您可以通过获取 Nodes 中的第 123 个元素来查找 NodeId 为 123 的节点。
- 节点: 在性能分析会话中记录的节点数组。每个条目包括:
- TotalDuration: 节点在 CPU 时间上花费的时间(以微秒为单位)。
- FunctionIds: 函数的唯一标识符数组。
- NodeIds: 节点 ID 数组。
- 函数: 在性能分析会话中记录的函数数组。
- TotalDuration: 函数在 CPU 时间上花费的时间(以微秒为单位)。
- 名称: 函数的名称(如果可用)。
- 源: 函数的源(如果可用)。
- 行: 函数的行号(如果可用)。
- 标志: 一个位域,指示任何特定的函数执行环境。目前可以具有以下值:
- 0: 第 0 位表示 IsNative 用于在原生代码生成下执行。
- 1: 第 1 位表示 IsPlugin 用于作为插件的一部分执行。
导出的性能分析数据示例
{
"Version":2,
"SessionStartTime":1704850750514,
"SessionEndTime":1704850751198,
"Categories":
[
{"Name":"Parallel Luau","NodeId":4},
{"Name":"Heartbeat","NodeId":1}
],
"Nodes":
[
{"TotalDuration":2530,"FunctionIds":[1],"NodeIds":[2]},
{"TotalDuration":2530,"FunctionIds":[2,5],"NodeIds":[3,7]},
{"TotalDuration":1267},
{"TotalDuration":7746,"FunctionIds":[3],"NodeIds":[5]},
{"TotalDuration":7746,"FunctionIds":[4],"NodeIds":[6]},
{"TotalDuration":7746},
{"TotalDuration":1263,"FunctionIds":[6],"NodeIds":[8]},
{"TotalDuration":1263,"FunctionIds":[7],"NodeIds":[9]},
{"TotalDuration":1263,"FunctionIds":[8],"NodeIds":[10]},
{"TotalDuration":1263}
],
"Functions":
[
{"Name":"main","TotalDuration":2530},
{"Source":"builtin_ManageCollaborators.rbxm.ManageCollaborators.Packages._Index.roblox_rodux-3.0.0.rodux.Store","Line":81,"TotalDuration":1267},
{"Name":"Script","TotalDuration":7746},
{"Source":"Workspace.Actor.Script","Line":1,"TotalDuration":7746},
{"Source":"builtin_DeveloperInspector.rbxm.DeveloperInspector.Packages._Index.DeveloperFramework.DeveloperFramework.UI.Components.Grid","Line":221,"TotalDuration":1263},
{"Source":"builtin_DeveloperInspector.rbxm.DeveloperInspector.Packages._Index.DeveloperFramework.DeveloperFramework.UI.Components.Grid","Name":"_update","Line":236,"TotalDuration":1263},
{"Source":"builtin_DeveloperInspector.rbxm.DeveloperInspector.Packages._Index.DeveloperFramework.DeveloperFramework.UI.Components.Grid","Name":"_getRange","Line":277,"TotalDuration":1263},
{"Source":"[C]","Name":"ScrollingFrame.CanvasPosition","TotalDuration":1263}
]
}