Принцип работы роутера Workbox

Workbox предоставляет мощный инструмент для управления кэшированием и обработкой сетевых запросов через сервис-воркеры. В основе этой функциональности лежит роутер, который определяет, как обрабатывать различные запросы, и позволяет реализовать стратегии кэширования, переадресации и других сетевых операций.

Регистрация роутов

Роут в Workbox — это объект, который связывает определённый паттерн запроса с конкретной стратегией обработки. Паттерн может быть:

  • Строкой — точное совпадение URL.
  • Регулярным выражением — гибкая фильтрация запросов.
  • Функцией-колбэком — пользовательская логика фильтрации, возвращающая true для обработки конкретного запроса.

Пример регистрации маршрута с использованием регулярного выражения:

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

registerRoute(
  ({ request }) => request.destination === 'image',
  new StaleWhileRevalidate({
    cacheName: 'images-cache',
    plugins: [
      // Возможные плагины, например, для ограничения размера кэша
    ],
  })
);

Здесь каждый запрос на изображение обрабатывается стратегией StaleWhileRevalidate, а кэш для изображений хранится отдельно.

Структура роутера

Роутер в Workbox представлен как централизованный объект, который хранит все зарегистрированные маршруты и определяет логику их применения при каждом запросе.

Основные элементы:

  1. Route — отдельный маршрут с паттерном и стратегией.
  2. Strategy — набор правил кэширования и сетевого взаимодействия.
  3. Handler — функция, вызываемая роутером для обработки запроса и возврата ответа.

Процесс обработки запроса можно описать пошагово:

  1. Сервис-воркер перехватывает fetch-событие.
  2. Роутер перебирает все зарегистрированные маршруты в порядке добавления.
  3. Для каждого маршрута вызывается проверка совпадения с запросом.
  4. Первый маршрут, совпадающий с запросом, применяет свою стратегию.
  5. Если ни один маршрут не совпал, запрос пропускается к сети без кэширования.

Стратегии обработки запросов

Роутер тесно связан с стратегиями, которые определяют поведение кэша и сети. Workbox предоставляет несколько встроенных стратегий:

  • CacheFirst — сначала проверяется кэш, затем сеть.
  • NetworkFirst — сначала сеть, затем кэш при неудаче.
  • StaleWhileRevalidate — отдаёт кэш, параллельно обновляя его из сети.
  • NetworkOnly — только сеть.
  • CacheOnly — только кэш.

Каждая стратегия может быть дополнена плагинами:

  • Ограничение размера и времени хранения кэша (ExpirationPlugin).
  • Принудительная установка заголовков для кэширования (CacheableResponsePlugin).
  • Логирование и обработка ошибок (BroadcastUpdatePlugin).

Приоритет маршрутов

Роутер обрабатывает маршруты в порядке регистрации, что позволяет задавать приоритет. Более конкретные маршруты следует регистрировать первыми, а универсальные шаблоны — последними.

Пример:

// Конкретный маршрут для API-запросов
registerRoute(
  /\/api\/.*$/,
  new NetworkFirst({
    cacheName: 'api-cache',
  })
);

// Универсальный маршрут для всех остальных запросов
registerRoute(
  ({ request }) => request.destination === 'document',
  new StaleWhileRevalidate({
    cacheName: 'pages-cache',
  })
);

Обработка ошибок и fallback

Роутер позволяет назначать fallback-ресурсы для случаев, когда запрос не может быть выполнен ни через сеть, ни через кэш. Это реализуется с помощью страховых стратегий или собственного обработчика:

import { setCatchHandler } from 'workbox-routing';

setCatchHandler(async ({ event }) => {
  if (event.request.destination === 'document') {
    return caches.match('/offline.html');
  }
  return Response.error();
});

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

Динамическая маршрутизация

Workbox поддерживает динамическое добавление маршрутов во время выполнения. Это позволяет адаптировать поведение сервис-воркера к изменяющимся условиям приложения, например:

import { workbox } from 'workbox-core';

self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'ADD_ROUTE') {
    registerRoute(
      event.data.pattern,
      new CacheFirst({
        cacheName: 'dynamic-cache',
      })
    );
  }
});

Логирование и отладка

Для сложных проектов Workbox предоставляет возможность отслеживать работу роутера. Включение debug-режима позволяет видеть, какой маршрут обрабатывает конкретный запрос:

import { setConfig } from 'workbox-core';

setConfig({ debug: true });

Каждое совпадение маршрута и использование стратегии будет выводиться в консоль, что значительно упрощает отладку и анализ поведения сервис-воркера.