Stale While Revalidate

Stale-While-Revalidate (SWR) — это стратегия кэширования, которая позволяет отдавать пользователю устаревшую версию ресурса из кэша сразу, а затем параллельно обновлять этот ресурс в кэше с сервера. Такой подход обеспечивает мгновенный отклик и одновременно поддерживает актуальность данных, минимизируя задержки при загрузке.


Основные принципы работы

  1. Мгновенная отдача кэшированного ресурса При запросе ресурса сначала возвращается версия из кэша, если она доступна. Это позволяет ускорить отображение интерфейса и снизить время ожидания для пользователя.

  2. Фоновое обновление кэша После отправки кэшированного ответа библиотека Workbox инициирует запрос к серверу для получения свежей версии ресурса. Когда новый ресурс получен, он заменяет старый в кэше.

  3. Следующие запросы получают свежие данные Пользователь получает обновлённый контент при последующих обращениях, что обеспечивает баланс между скоростью и актуальностью.


Реализация в Workbox

Workbox предоставляет готовый класс для реализации этой стратегии:

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

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

Пояснения к коду:

  • registerRoute — функция для регистрации маршрута и соответствующей стратегии.
  • request.destination — позволяет фильтровать тип ресурсов (скрипты, стили, изображения).
  • cacheName — имя кэша, куда будут сохраняться ресурсы.
  • plugins — массив плагинов Workbox для расширения функционала (например, ExpirationPlugin для ограничения количества кэшируемых элементов).

Плагины для расширения функционала

1. ExpirationPlugin Позволяет ограничить размер кэша или срок жизни ресурсов.

import { ExpirationPlugin } from 'workbox-expiration';

new StaleWhileRevalidate({
  cacheName: 'js-cache',
  plugins: [
    new ExpirationPlugin({
      maxEntries: 50, // максимум 50 файлов
      maxAgeSeconds: 7 * 24 * 60 * 60, // 7 дней
    }),
  ],
});

2. CacheableResponsePlugin Фильтрует кэшируемые ответы по статусу или заголовкам.

import { CacheableResponsePlugin } from 'workbox-cacheable-response';

new StaleWhileRevalidate({
  cacheName: 'api-cache',
  plugins: [
    new CacheableResponsePlugin({
      statuses: [0, 200], // кэшируем только успешные ответы
    }),
  ],
});

Примеры применения

  • JS и CSS файлы — ресурсы часто не меняются, и мгновенная отдача кэша ускоряет загрузку интерфейса.
  • API-запросы — если не критично отображать исключительно актуальные данные, SWR уменьшает задержку при отображении списка элементов или постов.
  • Изображения и мультимедиа — быстрая загрузка элементов интерфейса с фоновым обновлением.

Преимущества стратегии Stale-While-Revalidate

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

Потенциальные риски

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

Советы по оптимизации

  • Ограничивать размер кэша с помощью ExpirationPlugin, чтобы не переполнять память устройства.
  • Для критичных данных использовать комбинацию стратегий, например, NetworkFirst, если всегда нужен свежий контент.
  • Комбинировать SWR с CacheableResponsePlugin, чтобы исключить ошибки или пустые ответы из кэша.

Stale-While-Revalidate обеспечивает баланс между быстродействием и актуальностью данных, делая пользовательский интерфейс отзывчивым, даже при работе с сетевыми ресурсами, изменяющимися с течением времени.