25 / 36
Что такое Navigation Timing API?
Полный ответ
Каждая загрузка страницы создаёт одну запись типа PerformanceNavigationTiming:
JavaScript
const [nav] = performance.getEntriesByType('navigation');
// Полная хронология загрузки (в миллисекундах от начала навигации)
console.log({
// Этап 1: Подготовка
redirectTime: nav.redirectEnd - nav.redirectStart,
workerTime: nav.workerStart > 0 ? nav.fetchStart - nav.workerStart : 0,
// Этап 2: Сетевое подключение
dnsLookup: nav.domainLookupEnd - nav.domainLookupStart,
tcpConnect: nav.connectEnd - nav.connectStart,
tlsHandshake: nav.secureConnectionStart > 0
? nav.connectEnd - nav.secureConnectionStart
: 0,
// Этап 3: Запрос-ответ
requestTime: nav.responseStart - nav.requestStart, // TTFB (серверная часть)
responseTime: nav.responseEnd - nav.responseStart, // скачивание тела ответа
// Этап 4: Обработка документа
domParsing: nav.domInteractive - nav.responseEnd,
domContentLoaded: nav.domContentLoadedEventEnd - nav.domContentLoadedEventStart,
domComplete: nav.domComplete - nav.domInteractive,
// Этап 5: Событие load
loadEvent: nav.loadEventEnd - nav.loadEventStart,
// Общее время
totalTime: nav.loadEventEnd - nav.startTime,
});
Визуальная схема тайминга:
JavaScript
startTime
|
|-- redirectStart / redirectEnd (редиректы)
|-- workerStart (Service Worker)
|-- fetchStart (начало fetch)
|-- domainLookupStart / End (DNS)
|-- connectStart / secureConnectionStart / connectEnd (TCP + TLS)
|-- requestStart (отправка запроса)
|-- responseStart (первый байт = TTFB)
|-- responseEnd (весь ответ получен)
|-- domInteractive (DOM распарсен)
|-- domContentLoadedEventStart / End (DOMContentLoaded)
|-- domComplete (все ресурсы загружены)
|-- loadEventStart / loadEventEnd (window.onload)
Дополнительные свойства:
JavaScript
const [nav] = performance.getEntriesByType('navigation');
// Тип навигации
console.log(nav.type);
// 'navigate' -- обычный переход
// 'reload' -- перезагрузка
// 'back_forward' -- кнопки назад/вперёд
// 'prerender' -- предрендеренная страница
// Размер документа
console.log({
transferSize: nav.transferSize, // сжатый размер (по сети)
encodedBodySize: nav.encodedBodySize, // размер тела (сжатый)
decodedBodySize: nav.decodedBodySize, // размер тела (распакованный)
});
// Протокол
console.log(nav.nextHopProtocol); // "h2", "h3", "http/1.1"
📌 Реальные кейсы
Дашборд производительности:
JavaScript
function getNavigationMetrics() {
const [nav] = performance.getEntriesByType('navigation');
if (!nav) return null;
return {
// Сетевые метрики
dns: Math.round(nav.domainLookupEnd - nav.domainLookupStart),
tcp: Math.round(nav.connectEnd - nav.connectStart),
ttfb: Math.round(nav.responseStart - nav.requestStart),
download: Math.round(nav.responseEnd - nav.responseStart),
// DOM-метрики
domParse: Math.round(nav.domInteractive - nav.responseEnd),
domReady: Math.round(nav.domContentLoadedEventEnd - nav.startTime),
windowLoad: Math.round(nav.loadEventEnd - nav.startTime),
// Мета
protocol: nav.nextHopProtocol,
type: nav.type,
compressed: nav.transferSize < nav.decodedBodySize,
compressionRatio: nav.decodedBodySize > 0
? (1 - nav.transferSize / nav.decodedBodySize).toFixed(2)
: 'N/A',
};
}
// Отправка после полной загрузки
window.addEventListener('load', () => {
setTimeout(() => {
const metrics = getNavigationMetrics();
if (metrics) {
navigator.sendBeacon('/api/perf', JSON.stringify(metrics));
}
}, 0);
});
Сравнение Navigation Timing Level 1 и Level 2:
JavaScript
// ❌ Level 1 (устаревший) -- через performance.timing
const ttfb = performance.timing.responseStart - performance.timing.requestStart;
// ✅ Level 2 (текущий) -- через PerformanceNavigationTiming
const [nav] = performance.getEntriesByType('navigation');
const ttfb = nav.responseStart - nav.requestStart;
// Level 2 преимущества:
// -- Возвращает PerformanceEntry (совместим с PerformanceObserver)
// -- Точнее (high-resolution time)
// -- Содержит serverTiming, transferSize
Резюме
Navigation Timing API раскладывает загрузку страницы на точные этапы: DNS, TCP, TLS, TTFB, парсинг DOM, загрузка ресурсов. Используй Level 2 (getEntriesByType('navigation')) вместо устаревшего performance.timing. Это основной инструмент для диагностики медленных загрузок и мониторинга в production.