Кэширование API-ответов через runtimeCaching

sw-precache — это инструмент для автоматического генерации сервис-воркеров, который позволяет кэшировать статические ресурсы и API-ответы. В отличие от предзагруженного кэша (precache), который хранит файлы на этапе сборки, runtimeCaching предназначен для кэширования ресурсов, загружаемых динамически во время работы приложения. Этот подход критически важен для API-запросов, так как их содержимое может часто меняться и не известно заранее.

Конфигурация runtimeCaching

Для настройки кэширования API необходимо использовать опцию runtimeCaching при генерации сервис-воркера. Эта опция представляет собой массив объектов, где каждый объект описывает отдельное правило кэширования:

runtimeCaching: [
  {
    urlPattern: /\/api\/.*$/,
    handler: 'networkFirst',
    options: {
      cache: {
        name: 'api-cache',
        maxEntries: 50,
        maxAgeSeconds: 300
      }
    }
  }
]

Ключевые поля объекта:

  • urlPattern — регулярное выражение или функция для определения URL, к которым применяется правило. Для API-запросов часто используют паттерн /\/api\/.*$/.
  • handler — стратегия кэширования, определяющая порядок взаимодействия с сетью и кэшем.
  • options.cache — параметры кэша, включая имя, количество записей и время жизни.

Стратегии кэширования

sw-precache поддерживает несколько стратегий работы с кэшем, каждая из которых подходит для разных типов API:

  1. networkFirst Основной подход: сначала запрос к сети, при неудаче — кэш. Применяется для данных, которые должны быть актуальными, но требуется резервная копия для оффлайн-доступа.

  2. cacheFirst Сначала проверяется кэш, только при отсутствии данных выполняется сетевой запрос. Используется для редко обновляемых данных, например, справочной информации.

  3. fastest Одновременный запрос к сети и кэшу, возвращается первый доступный результат. Хорош для сокращения задержек, когда не критична абсолютная свежесть данных.

  4. networkOnly и cacheOnly Позволяют явно ограничить обработку только сетью или только кэшем. Могут использоваться для контроля трафика и управления доступом к данным.

Настройка параметров кэша

Опции кэша позволяют гибко управлять его размером и временем жизни:

  • name — имя кэша. Позволяет создавать отдельные кэши для разных API.
  • maxEntries — максимальное количество записей. Старые записи удаляются автоматически при превышении лимита.
  • maxAgeSeconds — время жизни кэшированных данных в секундах. После истечения кэш обновляется при следующем запросе.

Пример с расширенными настройками:

runtimeCaching: [
  {
    urlPattern: /\/api\/v1\/users\/.*/,
    handler: 'networkFirst',
    options: {
      cache: {
        name: 'users-cache',
        maxEntries: 100,
        maxAgeSeconds: 600
      },
      networkTimeoutSeconds: 5
    }
  }
]

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

Фильтрация и обработка ответов

Иногда API возвращает динамические данные, которые нужно фильтровать перед кэшированием. Для этого можно использовать функцию cacheableResponse:

options: {
  cache: {
    name: 'api-cache',
    maxEntries: 50,
    maxAgeSeconds: 300,
    cacheableResponse: {
      statuses: [0, 200]
    }
  }
}

Это позволит кэшировать только успешные ответы (200) и ответы типа opaque (0) для запросов к другим доменам через CORS.

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

  1. Кэширование новостей с API:
runtimeCaching: [
  {
    urlPattern: /\/api\/news\/.*/,
    handler: 'networkFirst',
    options: {
      cache: {
        name: 'news-cache',
        maxEntries: 30,
        maxAgeSeconds: 300
      }
    }
  }
]
  1. Кэширование изображений, загружаемых через API:
runtimeCaching: [
  {
    urlPattern: /\/api\/images\/.*/,
    handler: 'cacheFirst',
    options: {
      cache: {
        name: 'images-cache',
        maxEntries: 50,
        maxAgeSeconds: 86400
      }
    }
  }
]
  1. Комбинированная стратегия для оффлайн и онлайн режимов:
runtimeCaching: [
  {
    urlPattern: /\/api\/data\/.*/,
    handler: 'fastest',
    options: {
      cache: {
        name: 'data-cache',
        maxEntries: 100,
        maxAgeSeconds: 600
      }
    }
  }
]

Особенности интеграции

  • sw-precache автоматически генерирует сервис-воркер и интегрирует runtimeCaching с существующими кэшами.
  • При изменении конфигурации сервис-воркер нужно перегенерировать и обновить на сервере.
  • Использование runtimeCaching совместимо с precache, что позволяет комбинировать предзагруженные и динамические данные.
  • Для API, использующих аутентификацию, необходимо корректно передавать заголовки при сетевых запросах, чтобы кэширование не нарушало безопасность.

Оптимизация производительности

  • Разделение кэшей по типу данных (api-cache, images-cache) уменьшает вероятность удаления нужных записей при превышении лимитов.

  • Установка адекватного maxAgeSeconds обеспечивает баланс между свежестью данных и скоростью загрузки.

  • Для больших массивов данных лучше использовать networkFirst, чтобы пользователь получал актуальные данные, но при проблемах с сетью оставался оффлайн-доступ.

  • При необходимости обновления кэша можно вручную очистить устаревший кэш через методы caches.delete('cache-name').

Эффективное использование runtimeCaching в sw-precache позволяет построить гибкую стратегию кэширования API, обеспечивая быстрый доступ к данным и устойчивость приложения при слабом или отсутствующем интернет-соединении.