Комбинирование кэшированных и сетевых фрагментов

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

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


Стратегии получения данных

Cache First и Network First

Cache First используется для статических ресурсов, которые редко меняются. Если запрашиваемый ресурс присутствует в кэше, он возвращается немедленно. В противном случае выполняется сетевой запрос.

Network First подходит для динамических данных, где важно получать актуальную информацию. Сначала осуществляется попытка загрузки из сети, а при неудаче используется кэш.

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


Использование staleWhileRevalidate

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

Пример конфигурации маршрута:

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

registerRoute(
  ({ request }) => request.destination === 'script' || request.destination === 'style',
  new StaleWhileRevalidate({
    cacheName: 'static-resources',
    plugins: [
      {
        // Плагин для ограничения размера кэша
        cacheWillUpdate: async ({ response }) => {
          if (response && response.status === 200) return response;
          return null;
        }
      }
    ]
  })
);

Комбинирование разных источников

Для сложных приложений часто требуется объединять кэшированные и сетевые данные на уровне отдельных компонентов интерфейса. Например, можно кэшировать только шаблоны HTML и CSS, а контент загружать через API с Network First или Stale-While-Revalidate.

Пример подхода с использованием нескольких стратегий:

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

// Кэшируем статические изображения
registerRoute(
  ({ request }) => request.destination === 'image',
  new CacheFirst({
    cacheName: 'images-cache',
    plugins: [
      new workbox.expiration.ExpirationPlugin({
        maxEntries: 50,
        maxAgeSeconds: 30 * 24 * 60 * 60, // 30 дней
      }),
    ],
  })
);

// Динамические данные API
registerRoute(
  ({ url }) => url.pathname.startsWith('/api/'),
  new NetworkFirst({
    cacheName: 'api-cache',
    networkTimeoutSeconds: 3,
    plugins: [
      new workbox.expiration.ExpirationPlugin({
        maxEntries: 100,
        maxAgeSeconds: 5 * 60, // 5 минут
      }),
    ],
  })
);

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


Продвинутое комбинирование через cache.match и fetch

Workbox позволяет вручную управлять смешанными сценариями. Например, можно объединять фрагменты ответа из кэша и сети в одном HTML-шаблоне:

self.addEventListener('fetch', event => {
  if (event.request.url.includes('/dashboard')) {
    event.respondWith(
      (async () => {
        const cache = await caches.open('dashboard-cache');
        const cachedHtml = await cache.match('/dashboard/layout.html');
        const networkData = await fetch('/dashboard/data.json').then(res => res.json());
        
        // Генерация комбинированного ответа
        const combinedResponse = new Response(
          cachedHtml.text().then(html => html.replace('{{data}}', JSON.stringify(networkData))),
          { headers: { 'Content-Type': 'text/html' } }
        );
        return combinedResponse;
      })()
    );
  }
});

Такой метод позволяет кэшировать крупные шаблоны и одновременно подгружать свежие данные, не задерживая отображение интерфейса.


Использование плагинов Workbox для управления стратегиями

Workbox предоставляет плагины для автоматизации задач, связанных с комбинированием ресурсов:

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

Применение плагинов позволяет строить гибкие стратегии, комбинируя кэшированные и сетевые фрагменты с минимальными усилиями.


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

  • Статические ресурсы (JS, CSS, изображения) лучше кэшировать с Cache First, динамические данные с Network First или Stale-While-Revalidate.
  • Разделение ресурсов на категории позволяет минимизировать задержки загрузки интерфейса.
  • Обновление данных в фоне через Stale-While-Revalidate снижает количество сетевых запросов и повышает отзывчивость приложения.
  • Использование плагинов Workbox позволяет автоматизировать очистку устаревших данных и уведомление клиентов о свежих ресурсах.

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