Метрики в PWA и при офлайн-навигации

Web Vitals — это набор метрик, разработанных для оценки качества пользовательского опыта на веб-страницах. В контексте прогрессивных веб-приложений (PWA) и офлайн-навигации их использование имеет специфические особенности, так как приложение может работать как онлайн, так и полностью офлайн, а метрики должны корректно измерять производительность в обоих режимах.

Ключевыми показателями являются Largest Contentful Paint (LCP), First Input Delay (FID) и Cumulative Layout Shift (CLS). Для PWA и офлайн-навигации к ним добавляются Time to Interactive (TTI) и Total Blocking Time (TBT), поскольку они позволяют учитывать время, необходимое для полной интерактивности после загрузки кешированных ресурсов.


Подключение Web Vitals в PWA

Web Vitals предоставляются через официальную библиотеку web-vitals. В PWA интеграция требует учета особенностей Service Worker, так как данные о ресурсах могут приходить как из сети, так и из кеша.

import { getLCP, getFID, getCLS, getTTFB } from 'web-vitals';

// Отслеживание Largest Contentful Paint
getLCP(metric => {
  console.log('LCP:', metric.value);
});

// Отслеживание First Input Delay
getFID(metric => {
  console.log('FID:', metric.value);
});

// Отслеживание Cumulative Layout Shift
getCLS(metric => {
  console.log('CLS:', metric.value);
});

// Отслеживание Time to First Byte
getTTFB(metric => {
  console.log('TTFB:', metric.value);
});

Особенность PWA заключается в том, что Service Worker может возвращать ресурсы мгновенно из кеша. Поэтому LCP и TTFB могут показывать лучшие значения, чем при реальном сетевом подключении. Чтобы корректно учитывать опыт пользователей, рекомендуется логировать источник ресурса: кеш или сеть.


Обработка офлайн-сценариев

Офлайн-навигация в PWA требует специальной логики, так как стандартные Web Vitals ориентированы на загрузку через HTTP(S). Для правильного измерения метрик можно использовать следующие подходы:

  1. Идентификация офлайн-запросов Service Worker может добавлять к каждому отклику поле fromCache, которое потом используется для анализа метрик:
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(cachedResponse => {
      if (cachedResponse) {
        cachedResponse.headers.append('X-From-Cache', 'true');
        return cachedResponse;
      }
      return fetch(event.request);
    })
  );
});
  1. Измерение LCP для офлайн-страниц Если страница полностью рендерится из кеша, LCP вычисляется после вставки основного контента. В таких случаях важно запускать измерение после события DOMContentLoaded и любых асинхронных операций рендеринга:
document.addEventListener('DOMContentLoaded', () => {
  getLCP(metric => {
    console.log('Offline LCP:', metric.value);
  });
});
  1. События интерактивности Для FID и TBT офлайн-режим может быть чувствителен к задержкам JavaScript, особенно если приложение выполняет heavy computation после загрузки кеша. Поэтому рекомендуется:
  • Отслеживать requestIdleCallback и setTimeout для измерения времени блокировки.
  • Минимизировать синхронные операции при рендеринге офлайн-страниц.

Расширенные метрики и интеграция с аналитикой

В PWA важно не только измерять базовые Web Vitals, но и учитывать специфические сценарии:

  • Navigation Timing API позволяет фиксировать время загрузки ресурсов при переходе между страницами.
  • PerformanceObserver помогает отслеживать изменения layout и появление новых элементов для корректного расчета CLS.

Пример расширенного использования:

const observer = new PerformanceObserver(list => {
  list.getEntries().forEach(entry => {
    if (entry.entryType === 'layout-shift' && !entry.hadRecentInput) {
      console.log('CLS delta:', entry.value);
    }
  });
});

observer.observe({ type: 'layout-shift', buffered: true });

Для аналитики можно отправлять метрики в облачные сервисы с дополнительной информацией о состоянии сети (navigator.onLine), источнике ресурса и том, была ли страница загружена офлайн. Это позволяет выявлять потенциальные проблемы именно в PWA-режиме.


Практические рекомендации для PWA

  • LCP и TTFB могут быть аномально быстрыми при кешировании, поэтому фиксируйте источник ресурса.
  • FID и TBT важно измерять после полной инициализации JavaScript, включая офлайн-скрипты.
  • CLS особенно критичен при динамическом подгружении контента из IndexedDB или локального кеша.
  • Метрики должны логироваться и для онлайн, и для офлайн-навигации, чтобы понять реальный опыт пользователя.
  • Интеграция с PerformanceObserver и Navigation Timing API позволяет получить максимально точные значения для PWA.