借助 Angular、React、Vue 和 Svelte 等 Web 框架,您可以更轻松地大规模编写和维护复杂的 Web 应用。
不过,这些框架在浏览器应用模型之上引入了一个抽象层。事实上,开发者使用这些抽象概念编写的代码通常最终会被转译为难以理解的精简捆绑代码。因此,开发者可能难以充分利用 DevTools 的强大功能来调试和分析这些应用。
例如,在开发者工具中使用性能面板分析 Angular 应用时,您会看到以下内容:

以这种方式呈现的信息可能难以帮助您找出代码库中存在的性能瓶颈。毕竟,它缺少框架结构的上下文,并且显示的大部分信息都是精简代码。此外,很难区分与您编写的代码直接相关的活动、框架内部结构以及可能在同一网页上运行的其他第三方代码。
框架和抽象层作者的常见动机是实现自己的开发者工具扩展程序,以框架概念的形式呈现分析数据。在调试和分析使用特定框架构建的应用时,这些工具非常有用。不过,您通常需要将框架自有分析器中的框架数据与开发者工具性能面板中的浏览器运行时信息相关联。如果这两个数据源分别显示在不同的工具中,就很难发现和解决瓶颈问题,尤其是在应用变得越来越复杂时。以下是 Angular 开发者工具分析器中的个人资料可视化图表示例:

在理想情况下,开发者会有一个视图,其中两个数据源在同一上下文中一起显示,并映射到同一时间轴。
为此,我们与 Angular 团队合作,使用性能面板可扩展性 API 将 Angular 运行时数据直接引入性能面板。在这篇博文中,我们将了解该 API 的功能以及如何在 Angular 框架中使用它来实现这些功能。该实现可作为其他框架和抽象的示例,帮助它们通过检测自己的工具来改善开发者体验,并帮助开发者使用 Chrome 开发者工具。
什么是性能面板可扩展性 API?
借助该 API,您可以在与浏览器其余数据相同的时间轴内,向 Performance 面板轨迹添加自己的时间条目。您可以通过以下两种机制实现此目的:
- User Timing API
console.timeStamp
API
User Timing API
您可以使用 performance.mark
和 performance.measure
添加条目,如下所示:
// Mark used to represent the start of some activity you want to measure.
// In this case, the rendering of a component.
const renderStart = performance.now();
// ... later in your code
performance.measure("Component rendering", {
start: renderStart,
detail: {
devtools: {
dataType: "track-entry",
track: "Components",
color: "secondary",
properties: [
["Render reason", "Props changed"],
["Priority", "low"]
],
}
}
});
这样一来,时间轴中就会添加包含以下测量的组件轨道:

此 API 可让您将条目添加到性能时间轴缓冲区,同时在开发者工具的性能面板界面中显示这些条目。
如需详细了解此 API 和 devtools
对象,请参阅文档。
console.timeStamp
API
此 API 是 User Timing API 的轻量级替代方案。沿用之前的示例,您可以执行以下操作:
// Mark used to represent the start of some activity you want to measure.
// In this case, the rendering of a component.
const renderStart = performance.now();
// ... later in your code
console.timeStamp(
"Component rendering",
/* start time */ renderStart,
/* end time (current time) */ undefined,
/* track name */ "Components",
/* track group name */ undefined,
/* color */ "secondary"
);
此 API 提供了一种用于检测应用的高性能方法:与 User Timing API 替代方案不同,它不会创建缓冲数据。此 API 专门用于向开发者工具中的“性能”面板添加数据,这意味着当开发者工具未记录跟踪信息时,对该 API 的调用不会执行任何操作,从而显著提高速度,并适合对性能敏感的热路径。选择使用位置实参而不是包含所有自定义参数的对象,也是为了尽可能保持 API 的轻量级。
如需详细了解如何使用 console.timeStamp 扩展“性能”面板以及您可以在文档中传递的参数,请参阅相关内容。
Angular 如何集成开发者工具可扩展性 API
我们将了解 Angular 团队如何使用可扩展性 API 与 Chrome 开发者工具集成。
避免使用 console.timestamp 产生开销
自版本 20 起,Angular 的插桩与性能面板可扩展性 API 搭配使用。开发者工具中所需性能数据的精细度需要快速的 API,因此添加检测功能的 pull 请求 (60217) 选择使用 console.timeStamp
API。这样可以防止应用运行时性能受到分析 API 的潜在开销的影响。
插桩数据
为了清晰呈现 Angular 代码的运行情况以及运行原因,我们对启动和渲染流水线的多个部分进行了插桩,包括:
- 应用和组件引导。
- 组件创建和更新。
- 事件监听器和生命周期钩子的执行。
- 还有许多其他功能(例如,动态组件创建和延迟块渲染)。
颜色编码
颜色编码用于向开发者指示特定衡量条目所属的类别。例如,用于标记开发者编写的 TypeScript 代码执行情况的条目的颜色与 Angular 编译器生成的代码所用的颜色不同。
在以下屏幕截图中,您可以看到这会如何导致入口点(例如更改检测和组件处理)以蓝色显示、生成的代码以紫色显示,以及 TypeScript 代码(例如事件监听器和钩子)以绿色呈现。

请注意,传递给 API 的颜色实参不是 CSS 颜色值,而是一个语义令牌,该令牌会映射到与开发者工具界面相匹配的颜色。可能的值包括 primary
、secondary
和 tertiary,
,以及它们各自的 -dark
和 -light
变体,还有 error
颜色。
曲目
在撰写本文时,所有 Angular 运行时数据都添加到了同一轨道(标记为“🅰️ Angular”)中。不过,您可以向轨迹添加多个轨道,甚至可以对轨道进行分组。例如,假设对 console.timeStamp
API 的调用如下:
console.timeStamp("Component 1", componentStart1, componentEnd1, "Components", "Client", "primary");
console.timeStamp("Component 2", componentStart2, componentEnd2, "Components", "Client", "primary");
console.timeStamp("Hook 1", hookStart, hookEnd, "Hooks", "Client", "primary");
console.timeStamp("Fetch data base", fetchStart, fetchEnd, "Server", "primary");
您会看到数据以轨道形式整理,如下所示:

例如,当您有异步活动、多个并行运行的作业或足够独特的活动组时,使用单独的轨道会很有用,这些活动组值得在界面的不同区域中分开显示。
这对 Angular 开发者有何重要意义
这种直接集成旨在提供更直观、更全面的效果分析体验。通过直接在 **性能** 面板中显示 Angular 的内部性能数据,开发者将获得以下好处:
- 增强了可见性:在更广泛的浏览器时间轴中显示 Angular 特定的性能事件,例如组件渲染、更改检测周期等。
- 更好地了解:提供有关 Angular 内部流程的丰富上下文信息,帮助您更有效地找出性能瓶颈。
启用集成
自 Angular 版本 20 起,可扩展性 API 的使用已正式在开发 build 中提供。如需启用此功能,您必须在应用或开发者工具控制台中运行全局实用程序 `ng.enableProfiling()`。如需详细了解集成,请参阅 [Angular 文档](https://angular.dev/best-practices/profiling-with-chrome-devtools)
其他注意事项
需要考虑的一些重要事项。
源代码映射和缩减了大小的代码:
源代码映射是一种广泛使用的工具,旨在弥合捆绑 / 缩减的代码与其编写的对应代码之间的差距,因此...
源代码映射不是应该解决捆绑应用中代码缩减的问题吗?
虽然源映射确实很有用,但在分析复杂的已缩小的 Web 应用时,它们并不能完全消除挑战。借助源代码映射,DevTools 可以将缩减了大小的代码映射回原始源代码,从而简化调试过程。不过,仅依靠源映射进行性能分析仍存在一些限制。例如,仅使用源代码映射很难选择以何种方式直观地分隔框架内部代码和已编写的代码。另一方面,可扩展性 API 提供了灵活性,可实现这种区分,并以开发者认为最方便的方式呈现。
Chrome 开发者工具扩展程序:
使用 DevTools API 的 Chrome 扩展程序是一种广泛使用的扩展开发者工具的工具。
现在有了这个 API,是否不再需要或不建议使用专用分析器(例如 Chrome 开发者工具扩展程序)?
不会,此 API 并非旨在取代或阻止开发专用分析器(例如 Chrome DevTools 扩展程序)。这些工具仍可提供根据特定需求量身定制的专业功能、可视化图表和工作流程。性能面板可扩展性 API 旨在将自定义数据与性能面板中的浏览器可视化图表无缝集成。
未来的发展方向
可扩展性 API 的前景。
使用更多框架和抽象层
我们很高兴看到其他框架和抽象层采用该 API 来改善开发者的分析体验。例如,React 已为其框架实现了该 API 的实验性采用。此插桩可显示客户端和服务器组件呈现以及 React 调度 API 数据。如需详细了解此功能以及如何在 React 中启用此功能,请访问 React 的页面。
正式版 build
此 API 的目标之一是与框架和抽象提供方合作,以便在正式版 build 中采用并启用插桩。这可能会对使用这些抽象概念开发的应用的性能产生重大影响,因为开发者能够像用户一样分析应用。我们认为,console.timeStamp
API 凭借其速度和低开销,可以实现这一目标。不过,目前框架仍在对 API 进行实验,并探索哪些类型的插桩对开发者来说更具可伸缩性和实用性。