Хуки жизненного цикла запроса

Workbox предоставляет гибкий механизм для работы с кэшированием и управлением сетевыми запросами через сервис-воркеры. Одним из ключевых компонентов этой системы являются хуки жизненного цикла запроса (Lifecycle Hooks), которые позволяют вмешиваться в процесс обработки запросов на различных стадиях, изменять их поведение и управлять кэшированием.


Основные стадии жизненного цикла запроса

Жизненный цикл запроса в Workbox можно разделить на несколько ключевых этапов:

  1. beforeFetch – этап до выполнения сетевого запроса. Здесь можно модифицировать объект запроса, добавлять заголовки или перенаправлять запрос на другой URL.

  2. fetchDidFail – срабатывает, если сетевой запрос завершился с ошибкой. Используется для обработки сбоев сети, fallback-логики и логирования.

  3. cacheWillUpdate – срабатывает перед записью ответа в кэш. Позволяет контролировать, какой ответ будет кэшироваться, проверять статус кода, размер или тип контента.

  4. cacheDidUpdate – срабатывает после успешной записи ответа в кэш. Подходит для уведомления других частей приложения о новых данных, например, для обновления индикаторов контента.

  5. cachedResponseWillBeUsed – вызывается перед использованием кэшированного ответа. Можно вернуть кастомный ответ вместо того, что был найден в кэше, или добавить дополнительную логику проверки свежести.

  6. requestWillFetch – вызывается перед отправкой сетевого запроса. Позволяет модифицировать запрос, добавлять токены авторизации или включать дополнительные параметры.


Примеры использования хуков

Модификация запроса перед отправкой:

import {registerRoute} from 'workbox-routing';
import {NetworkFirst} from 'workbox-strategies';

registerRoute(
  ({request}) => request.destination === 'script',
  new NetworkFirst({
    cacheName: 'js-cache',
    plugins: [{
      requestWillFetch: async ({request}) => {
        const newRequest = new Request(request.url, {
          ...request,
          headers: {
            ...request.headers,
            'X-Custom-Header': 'MyHeaderValue'
          }
        });
        return newRequest;
      }
    }]
  })
);

Контроль кэширования ответов:

import {StaleWhileRevalidate} from 'workbox-strategies';

const cachePlugin = {
  cacheWillUpdate: async ({response}) => {
    if (response && response.status === 200 && response.type === 'basic') {
      return response;
    }
    return null; // не кэшировать невалидные ответы
  },
  cacheDidUpdate: ({cacheName, request, oldResponse, newResponse}) => {
    console.log(`Кэш обновлен: ${request.url}`);
  }
};

registerRoute(
  ({request}) => request.destination === 'image',
  new StaleWhileRevalidate({
    cacheName: 'images-cache',
    plugins: [cachePlugin]
  })
);

Обработка неудачных сетевых запросов:

import {NetworkFirst} from 'workbox-strategies';

const fallbackPlugin = {
  fetchDidFail: async ({originalRequest}) => {
    console.error(`Ошибка при загрузке: ${originalRequest.url}`);
    return caches.match('/offline.html'); // возвращаем offline-страницу
  }
};

registerRoute(
  ({request}) => request.mode === 'navigate',
  new NetworkFirst({
    cacheName: 'pages-cache',
    plugins: [fallbackPlugin]
  })
);

Отличия хуков Workbox от обычного Fetch API

  • Контекст плагина: хуки Workbox интегрированы в стратегию кэширования и получают контекст (request, response, cacheName), что упрощает управление кэшированием.
  • Асинхронная обработка: каждый хук поддерживает промисы, позволяя выполнять сетевые запросы или сложную обработку данных перед возвратом результата.
  • Цепочка хуков: несколько плагинов можно комбинировать, и они будут вызваны последовательно в порядке подключения.

Рекомендации по использованию хуков

  • Для критически важных запросов использовать requestWillFetch и fetchDidFail, чтобы обеспечить надежную доставку данных.
  • Для контроля качества кэша – cacheWillUpdate и cacheDidUpdate, чтобы не сохранять некорректные или устаревшие ответы.
  • Для динамического изменения кэшированного контента – cachedResponseWillBeUsed, чтобы проверять свежесть данных и возвращать актуальные результаты.

Особенности работы с плагинами

Каждый хук реализуется через плагины Workbox, которые можно передавать в стратегии кэширования (NetworkFirst, CacheFirst, StaleWhileRevalidate). Один плагин может реализовывать несколько хуков, что обеспечивает гибкость и повторное использование логики в разных стратегиях и маршрутах.

Пример комбинированного плагина:

const myPlugin = {
  requestWillFetch: async ({request}) => {
    return new Request(request, {headers: {'Authorization': 'Bearer TOKEN'}});
  },
  cacheWillUpdate: async ({response}) => response && response.status === 200 ? response : null,
  cacheDidUpdate: ({request}) => console.log(`Обновлен кэш для ${request.url}`)
};

Этот подход позволяет централизованно управлять запросами и кэшированием, уменьшая дублирование кода и повышая предсказуемость поведения сервис-воркера.


Хотите, я подготовлю детальную схему жизненного цикла запроса с указанием всех хуков Workbox, чтобы наглядно видеть, когда какой хук срабатывает? Это сильно облегчает понимание и отладку сервис-воркеров.