Веб-фреймворки, такие как Angular, React, Vue и Svelte, упрощают написание и поддержку сложных масштабируемых веб-приложений.
Однако эти фреймворки добавляют слой абстракции поверх модели приложения браузера. Фактически, код, написанный разработчиками с использованием этих абстракций, обычно транспилируется в нечитаемый, минифицированный и упакованный код. В результате полноценное использование возможностей DevTools для отладки и профилирования таких приложений может быть сложной задачей для разработчиков.
Например, при профилировании приложения Angular с помощью панели «Производительность» в DevTools вы увидите следующее:

При таком представлении информации может быть сложно определить узкие места производительности в вашей кодовой базе. Ведь в ней отсутствует контекст конструкций фреймворка, а значительная часть отображаемой информации представлена в виде минифицированного кода. Кроме того, сложно отличить действия, непосредственно связанные с написанным вами кодом, внутренними компонентами фреймворка и другим сторонним кодом, который может выполняться на той же странице.
Распространенной мотивацией для разработчиков фреймворков и абстракций является реализация собственных расширений DevTools, которые представляют данные профилирования в соответствии с концепциями фреймворка. Эти инструменты очень полезны при отладке и профилировании приложений, созданных с использованием конкретного фреймворка. Однако чаще всего вам потребуется сопоставить данные фреймворка в его собственном профилировщике с информацией о времени выполнения браузера на панели «Производительность» в DevTools. Представление этих двух источников данных по отдельности в независимых инструментах затрудняет выявление и устранение узких мест, особенно по мере усложнения приложения. Вот пример визуализации профиля в Angular DevTools Profiler:

В идеальном мире разработчики получили бы представление, в котором два источника данных отображались бы вместе в одном контексте, сопоставленном с одной и той же временной шкалой.
По этой причине мы объединились с командой Angular, чтобы перенести данные среды выполнения Angular прямо на панель «Производительность» с помощью API расширения панели «Производительность» . В этой статье мы рассмотрим возможности этого API и то, как он использовался во фреймворке Angular для достижения этой цели. Эта реализация может послужить примером для других фреймворков и абстракций, стремящихся улучшить свой опыт разработки, оснастив свои собственные инструменты и помогая разработчикам использовать Chrome DevTools.
Что такое API расширяемости панели производительности?
API позволяет добавлять собственные записи времени в трассировку панели «Производительность» на той же временной шкале, что и остальные данные браузера. Существует два механизма, позволяющих это сделать:
- API пользовательского времени
- API
console.timeStamp
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 позволяет добавлять записи в буфер временной шкалы производительности , а также отображать их в пользовательском интерфейсе панели производительности DevTools.
Дополнительную информацию об этом API и объекте devtools
можно найти в документации .
API console.timeStamp
Этот API — облегчённая альтернатива 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 добавляет данные исключительно на панель **Производительность** в DevTools. Это означает, что когда DevTools не записывает трассировку, вызовы API не выполняются (ничего не делают), что значительно ускоряет его и делает подходящим для критически важных для производительности горячих путей. Выбор позиционных аргументов вместо объекта, содержащего все параметры настройки, также позволяет максимально упростить API.
Дополнительную информацию об использовании console.timeStamp для расширения панели «Производительность» и параметрах, которые можно передать, можно найти в документации .
Как Angular интегрировал API расширяемости DevTools
Мы рассмотрим, как команда Angular использовала API расширяемости для интеграции с Chrome DevTools.
Избегайте накладных расходов с console.timestamp
Инструментарий Angular с API расширения панели производительности доступен с версии 20. Требуемый уровень детализации данных о производительности в DevTools требует быстрого API, поэтому в запросе на включение изменений ( 60217 ), добавляющем инструментарий, было выбрано использование API console.timeStamp
. Это предотвращает влияние на производительность выполнения приложения потенциальных накладных расходов, связанных с API профилирования.
Инструментированные данные
Чтобы получить четкое представление о том, какой код Angular выполняется, а также почему он вообще запускается, инструментируются несколько частей конвейеров запуска и рендеринга, в том числе:
- Начальная загрузка приложений и компонентов.
- Создание и обновление компонентов.
- Выполнение прослушивателей событий и перехватов жизненного цикла.
- Многие другие (например, динамическое создание компонентов и отложенный рендеринг блоков).
Цветовая кодировка
Цветовое кодирование используется для обозначения категории, к которой относится определённая запись измерения. Например, цвета, используемые для записей, отмечающих выполнение кода TypeScript, написанного разработчиком, отличаются от цветов, используемых для кода, созданного компилятором Angular.
На следующем снимке экрана вы можете увидеть, как это приводит к появлению точек входа (например, обнаружения изменений и обработки компонентов) синего цвета, сгенерированного кода фиолетового цвета и кода TypeScript (например, прослушивателей событий и хуков), отображаемого зеленым цветом.

Обратите внимание, что аргумент цвета, передаваемый в API, — это не значение цвета CSS, а семантический токен, сопоставленный с цветом, соответствующим интерфейсу DevTools. Возможные значения: primary
, secondary
и tertiary,
с соответствующими им вариантами -dark
и -light
, а также цвет error
.
Треки
На момент написания статьи все данные среды выполнения Angular добавляются в один и тот же трек (с пометкой «🅰️ Angular»). Однако можно добавить несколько треков в трассировку и даже сгруппировать их. Например, вот следующие вызовы API console.timeStamp
:
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 вы сможете эффективнее выявлять узкие места производительности.
Включение интеграции
Использование API расширения официально доступно в сборках разработки, начиная с версии Angular 20. Чтобы включить его, необходимо запустить глобальную утилиту `ng.enableProfiling()` в вашем приложении или в консоли DevTools. Подробнее об интеграции см. в [документации Angular] ( https://angular.dev/best-practices/profiling-with-chrome-devtools ).
Другие соображения
Некоторые важные соображения, которые следует принять во внимание.
Исходные карты и минифицированный код:
Карты исходного кода — это широко используемый инструмент, призванный сократить разрыв между упакованным/минифицированным кодом и его авторским аналогом, поэтому...
Разве карты исходного кода не должны решать проблему минимизированного кода в пакетных приложениях?
Хотя карты исходного кода действительно полезны, они не полностью устраняют проблемы при профилировании сложных минимизированных веб-приложений. Карты исходного кода позволяют DevTools сопоставлять минимизированный код с исходным, упрощая отладку. Однако использование только карт исходного кода для анализа производительности может иметь определённые ограничения. Например, выбор способа визуального разделения внутренних компонентов фреймворка и исходного кода с помощью одних только карт исходного кода усложняется. С другой стороны, API расширяемости обеспечивает гибкость для достижения этого различия и представления его в наиболее удобном для разработчика виде.
Расширения Chrome DevTools:
Расширения Chrome, использующие API DevTools, являются широко используемым инструментом для расширения возможностей инструментов разработчика.
Являются ли специализированные профилировщики (например, расширения Chrome DevTools) ненужными или нерекомендуемыми теперь, когда доступен этот API?
Нет, этот API не предназначен для замены или предотвращения разработки специализированных профилировщиков, таких как расширения Chrome DevTools. Они по-прежнему могут предлагать специализированные функции, визуализации и рабочие процессы, адаптированные к конкретным потребностям. API расширения панели «Производительность» предназначен для обеспечения бесшовной интеграции пользовательских данных с визуализациями браузера на панели «Производительность» .
Путь вперед
Перспектива расширяемости API.
Работайте с большим количеством фреймворков и абстракций
Мы рады, что другие фреймворки и абстракции используют этот API для улучшения возможностей профилирования для своих разработчиков. Например, React реализовал экспериментальное внедрение API для своего фреймворка. Этот инструментарий позволяет визуализировать данные рендеринга клиентских и серверных компонентов, а также данные API планирования React. Узнайте больше о нём и о том, как включить его, на странице React .
Производственные сборки
Одна из целей этого API — сотрудничество с фреймворками и поставщиками абстракций в целом для внедрения и поддержки инструментария в производственных сборках. Это может существенно повлиять на производительность приложений, разработанных с использованием этих абстракций, поскольку разработчики смогут профилировать приложение с учётом того, как его используют пользователи. Мы считаем, что API console.timeStamp
позволяет достичь этого благодаря своей скорости и низким накладным расходам. Однако в настоящее время фреймворки всё ещё экспериментируют с этим API и ищут, какие виды инструментария будут более масштабируемыми и полезными для разработчиков.