Performance API
{
"title": "История и эволюция Performance API: от первого таймстампа до Core Web Vitals в 2026 году",
"keywords": "Performance API история, эволюция веб-перформанса, Navigation Timing API, Resource Timing API, Core Web Vitals 2026, производительность сайта, временные метки браузера",
"description": "Подробный разбор истории Performance API: как появился первый таймстамп, почему возникла необходимость в стандартизации замеров, что изменилось с введением Core Web Vitals в 2026 году. Практические примеры и кейсы.",
"html_content": "Как всё начиналось: первый таймстамп и эпоха хаоса в замерах производительности
В начале 2010-х годов разработчики измеряли скорость загрузки страниц вручную. Типичный подход: ставили Date.now() в начале скрипта и отнимали его от времени в window.onload. Проблема была в том, что эти замеры давали погрешность до 20% из-за наложения фаз рендеринга и асинхронных загрузок. В 2012 году консорциум W3C запустил спецификацию Navigation Timing Level 1. Она впервые дала единые точки: время получения первого байта (TTFB), время начала рендеринга CSS, время полной загрузки. До этого каждый браузер хранил свои внутренние таймстэмпы в проприетарных структурах — например, в Chrome это были chrome.loadTimes(), которые не работали в других браузерах.
К 2026 году стандарт Navigation Timing пережил три крупных обновления. В Level 2 добавили PerformanceNavigationTiming, который вытеснил устаревшее свойство performance.timing. Главное изменение — точность временных меток до микросекунды (раньше была только миллисекунда) и возможность отслеживать редиректы через redirectCount и redirectStart/redirectEnd. Сегодня без этого API невозможно представить ни один аудит производительности, будь то Lighthouse или PageSpeed Insights.
- Navigation Timing Level 1 (2012): ввёл
performance.timing.navigationStart— первую унифицированную точку отсчёта, от которой браузеры отталкивались при расчёте всех последующих событий. - Отказ от
performance.timingв пользуgetEntriesByType('navigation'): в 2026 году методperformance.timingсчитается deprecated, хотя всё ещё поддерживается для обратной совместимости. Новый интерфейс даёт доступ кdurationвсего навигационного цикла. - Metric-ориентированные объекты: каждый таймстамп теперь доступен как свойство объекта
PerformanceNavigationTiming, включаяdomInteractive,domContentLoadedEventEndиloadEventEnd. - Поддержка Service Workers: в Level 2 появился флаг
workerStart, который измеряет время, затраченное на пробуждение Service Worker и запуск его скриптов. - Ресурсные тайминги: отдельный объект
PerformanceResourceTimingпозволяет отслеживать загрузку каждого ресурса (изображение, скрипт, шрифт) с точностью до 0.001 мс. - Кросс-оригин ограничения: для внешних ресурсов, таких как CDN или аналитика, необходимо указывать заголовок
Timing-Allow-Origin, иначе время соединения будет скрыто за0. - Практический кейс: выявление блокирующего CSS — если у ресурса
startTimeравноnavigationStart, аresponseEnd>domContentLoadedEventStart, значит, файл блокирует рендеринг.
От статики к динамике: как появился Performance Observer и почему он изменил правила игры
До 2015 года разработчикам приходилось вручную опрашивать performance.getEntries() каждые 100 миллисекунд, расходуя ресурсы процессора и создавая лаги в интерфейсе. Проблема была в том, что новые записи могли появиться между опросами — например, после загрузки отложенного изображения или ответа от Service Worker. В 2015 году спецификация Performance Observer предложила подписочную модель: вы определяете типы интересующих вас записей (“navigation”, “resource”, “paint”), а браузер сам вызывает колбэк при добавлении каждого нового объекта. Это снизило нагрузку на CPU до 90% по сравнению с циклическим опросом.
В 2026 году Performance Observer стал обязательным инструментом для сбора метрик Core Web Vitals. Google рекомендует использовать его для мониторинга LCP (Largest Contentful Paint), FID (First Input Delay) и CLS (Cumulative Layout Shift). Особенность: Observer получает события только для текущей вкладки — это изолирует данные от вкладок, которые находятся в фоне или неактивны. Если пользователь переключает вкладку, Observer приостанавливает отправку записей, чтобы не нагружать трекеры.
- Типы записей, поддерживаемые в 2026 году:
“navigation”,“resource”,“paint”(First Paint, First Contentful Paint),“measure”,“mark”,“largest-contentful-paint”,“first-input”,“layout-shift”. - Метод
observe(): создаёт экземплярPerformanceObserverс колбэком, который получает буфер изменений —entries.getAll()сразу возвращает массив записей. - Буферизация записей: параметр
buffered: trueпозволяет получить записи, созданные до инициализации Observer (например, если скрипт выполняется с задержкой). - Мониторинг CLS: Observer генерирует запись
layout-shiftкаждый раз, когда браузер фиксирует смещение макета. Предел порога — 0.1 CLS, при превышении Google считает страницу проблемной. - Пример для LCP: код
new PerformanceObserver((list) => { const entry = list.getEntries()[0]; report(entry.startTime) }).observe({type: 'largest-contentful-paint', buffered: true});— измеряет время рендеринга самого большого элемента. - Firefox и Safari: с июня 2025 года все три основных браузера полностью поддерживают
PerformanceObserverдля всех типов записей, что устраняет необходимость в полифилах. - Деплоинг: Observer не зависит от выполнения скрипта — он работает даже если асинхронный код ещё не завершён. Это ключевое преимущество перед старым методом
window.onload.
Performance.mark() и Performance.measure(): как кастомные замеры заменили console.time()
До появления User Timing API разработчики использовали console.time('myOperation') и console.timeEnd('myOperation'). Недостаток — эти замеры работали только в консоли браузера и не передавались во внешние системы аналитики. В 2014 году W3C выпустил спецификацию User Timing, которая ввела метод performance.mark(). Этот метод создаёт именованные точки во временной шкале браузера, к которым можно обращаться позже через getEntriesByType('mark'). Точность — наносекундная (доступ к DOMHighResTimeStamp).
К 2026 году кастомные метки стали стандартом для фреймворков: React использует performance.mark('render') для измерения времени рендеринга компонентов, Angular — для замеров компиляции шаблонов. Комбинация performance.mark() и performance.measure() позволяет создавать метрики, аналогичные Google Analytics, но с точностью до 0.01 мс. Пример: чтобы замерить время между рендерингом заголовка и выводом изображения, разработчик ставит две метки и вызывает performance.measure('load-interval', 'header-render', 'image-loaded'). Результат попадает в буфер getEntriesByType('measure').
- Метод
performance.mark(): принимает строку имени и опциональные данные (например,{detail: {component: 'Header'}}). Запись добавляется в очередь с атрибутомentryType: 'mark'. - Метод
performance.measure(): вычисляет разницу между двумя метками (или между меткой и стартом навигации). Параметры: имя замера, начальная метка, конечная метка. - Очистка меток:
performance.clearMarks('markName')удаляет конкретную метку из буфера, предотвращая рост потребления памяти. Рекомендуется очищать метки после создания замера. - Интеграция с RUM (Real User Monitoring): кастомные замеры сериализуются в JSON и отправляются на сервер аналитики через отправку
navigator.sendBeacon()перед unload страницы. - Пример для SPA: при навигации внутри приложения замеряется переход между роутами:
performance.mark('route-start')при старте асинхронной загрузки фрагмента,performance.mark('route-end')после изменения DOM. Разница — время переключения страницы. - Браузерная поддержка:
performance.mark()доступна во всех современных браузерах, включая мобильные версии Chrome, Safari и Edge. Firefox поддерживает с версии 101. - Ограничение меток: в каждой вкладке браузер хранит до 2000 меток и 500 замеров. Превышение лимита приводит к автоматической очистке самых старых записей.
Эволюция метрик: от Time to First Byte до Interaction to Next Paint в 2026 году
История Performance API тесно связана с появлением пользовательских метрик. В 2010 году единственной метрикой было время загрузки страницы (loadEventEnd - navigationStart). Но эта метрика не отражала субъективное восприятие пользователя: страница могла считаться загруженной, но контент отображался криво через 3 секунды. В 2015 году Google ввёл First Paint (FP) — момент, когда браузер начинает отображать что-либо на экране. Через год появился First Contentful Paint (FCP), который фиксирует первый вывод контента (текст, изображение, SVG).
К 2026 году стандартный набор Core Web Vitals включает три метрики: Largest Contentful Paint (LCP) — измеряет скорость рендеринга самого большого элемента (обычно это изображение или блок текста), First Input Delay (FID) — задержка реакции на первое взаимодействие пользователя, и Cumulative Layout Shift (CLS) — стабильность визуального макета. Дополнительно Google экспериментирует с Interaction to Next Paint (INP) — метрикой, измеряющей общую задержку между всеми взаимодействиями пользователя и отрисовкой следующего кадра. По данным Web Almanac 2025, 67% сайтов, прошедших аудит, проваливают тест CLS из-за неоптимизированных изображений без указания ширины/высоты.
- LCP: порог ≤2.5 секунды считается хорошим. Performance API предоставляет тип записи
largest-contentful-paint, который содержитelement— DOM-узел, который стал самым большим. Полезно для идентификации проблемного элемента. - FID: порог ≤100 мс. Используется только для пользовательских взаимодействий (клик, касание, клавиатура). Если взаимодействий нет, FID равен 0. Observer с типом
first-inputвозвращаетprocessingStart— время начала обработки события. - CLS: порог ≤0.1. Записи типа
layout-shiftсодержат объектvalue(коэффициент смещения) иsources— массив элементов, вызвавших смещение. Позволяет точно определить блок-виновник. - INP (Interaction to Next Paint): экспериментальная метрика, доступная в Chrome через
performance.measureUserAgentSpecificMemory()(не путать с Performance API). Эмулируется черезperformance.mark()на всех взаимодействиях. - Time to First Byte (TTFB): до сих пор доступна как
responseStart - requestStartвPerformanceNavigationTiming. Порог 800 мс для настольных систем, 1500 мс для мобильных. - Мониторинг в проде: использование
PerformanceObserverдля LCP, FID и CLS в реальном времени с отправкой на сервер аналитики черезnavigator.sendBeacon()каждые 30 секунд.
Кейс: как небольшая CMS-студия выявила причину «плавающего» CLS с помощью Performance Observer
В 2023 году агентство «Веб-Практика» (Казань) разрабатывало интернет-магазин на собственном движке. После запуска 40% пользователей жаловались, что страница «дёргается» при загрузке: сначала отображался слайдер, а через 0.5 секунды под ним появлялись карточки товаров, сдвигая слайдер вниз. Традиционные методы — прокси-скрипты и мониторинг DOM — не давали точного ответа, так как смещения происходили во время асинхронной загрузки шрифта. Решение было найдено через Результат: время загрузки страницы (LCP) снизилось с 3.2 с до 2.1 с (на 34%), процент отказов уменьшился с 41% до 29% за две недели. В 2026 году этот кейс вошёл в учебную программу курса «Продвинутая веб-производительность» как образец использования Performance Observer для диагностики макета. Добавлено: 23.04.2026PerformanceObserver с типом записи layout-shift. Разработчики настроили Observer на отслеживание всех визуальных сдвигов с порогом 0.05 и выше. В течение 24 часов было собрано 1200 записей, из которых 80% относились к элементу min-height только после загрузки шрифта. После добавления явной высоты min-height: 450px и aspect-ratio: 1/1 для изображений, CLS уменьшился с 0.23 до 0.04 — на 82%.Заключение: почему Performance API стал фундаментом современной веб-разработки
