Метрики — FCP, TTFB, TTI, TBT

FCP, TTFB, TTI и TBT — дополнительные метрики производительности, которые вместе с Core Web Vitals (LCP, INP, CLS) дают полную картину скорости загрузки и интерактивности страницы.

Зачем нужно

Core Web Vitals — финальный результат для Google. Диагностические метрики (TTFB, FCP, TTI, TBT) помогают найти причину проблем: высокий TTFB → проблема с сервером; большой TBT → тяжёлый JavaScript. Понимание каждой метрики — навигация по оптимизации.

Где используется

  • Lighthouse отчёты — все четыре метрики в "Diagnostics"
  • WebPageTest Waterfall — TTFB как baseline
  • Performance Budget — TTI как порог интерактивности
  • Server monitoring — TTFB как SLA-метрика

Основной контент

Хронология метрик

0ms ────────────────────────────────────────────────────────→ время

  ↓ TTFB         ↓ FCP              ↓ TTI         ↓ TBT (сумма)
  │←TTFB→│ │←────FCP────→│ │←──────TTI──────────→│
  │              │                   │
Navigation   First paint      Consistently interactive
  start      (any content)     (no long tasks > 50ms)

Описание метрик

TTFB — Time to First Byte
  Время от навигации до первого байта HTML от сервера
  Good: < 800ms | Poor: > 1800ms
  Причины проблем: медленный сервер, отсутствие CDN, долгий DB запрос

FCP — First Contentful Paint
  Первый рендер любого контента (текст, изображение, SVG)
  Good: < 1.8s | Poor: > 3.0s
  Причины: render-blocking CSS/JS, медленный TTFB

TTI — Time to Interactive (устаревшая, заменена INP)
  Момент, когда страница надёжно реагирует на ввод
  Good: < 3.8s | Poor: > 7.3s
  Причины: тяжёлый JS, долгие tasks в main thread

TBT — Total Blocking Time
  Сумма времён задач > 50ms (blocking portion) между FCP и TTI
  Good: < 200ms | Poor: > 600ms
  Коррелирует с INP, показывает "загруженность" main thread

Измерение через Performance API

// TTFB
const [navEntry] = performance.getEntriesByType('navigation');
const ttfb = navEntry.responseStart - navEntry.requestStart;
console.log(`TTFB: ${ttfb}ms`);

// FCP
const observer = new PerformanceObserver(list => {
  for (const entry of list.getEntries) {
    if (entry.name === 'first-contentful-paint') {
      console.log(`FCP: ${entry.startTime}ms`);
    }
  }
});
observer.observe({ entryTypes: ['paint'] });

// TBT — через Long Tasks API
let totalBlockingTime = 0;
const longTaskObserver = new PerformanceObserver(list => {
  for (const entry of list.getEntries) {
    const blockingTime = entry.duration - 50;
    if (blockingTime > 0) {
      totalBlockingTime += blockingTime;
    }
  }
});
longTaskObserver.observe({ entryTypes: ['longtask'] });

// После TTI:
console.log(`TBT: ${totalBlockingTime}ms`);

Диагностика по метрикам

Высокий TTFB (> 800ms):
  → Добавить CDN
  → Оптимизировать запросы к БД
  → Включить кеширование на сервере

Высокий FCP при низком TTFB:
  → Render-blocking CSS/JS
  → Inline Critical CSS
  → defer/async для JS

Высокий TBT/плохой INP:
  → Разбить Long Tasks (>50ms)
  → Web Workers для тяжёлых вычислений
  → Code splitting, lazy loading
  → startTransition для несрочных обновлений

Частые ошибки

  • Оптимизировать TTFB без анализа FCP — могут быть render-blocking ресурсы
  • Ориентироваться на TTI вместо INP — TTI устарел с марта 2024
  • Игнорировать TBT как "не SEO метрику" — TBT сильно коррелирует с INP
  • Измерять только в Lighthouse (lab) без проверки в реальных условиях (CrUX)

Связанные темы

Ресурсы