Интеграция с UI-фреймворками

Workbox — это мощная библиотека для упрощения создания сервис-воркеров и реализации стратегий кэширования в веб-приложениях. При работе с современными UI-фреймворками, такими как React, Vue или Angular, её возможности позволяют повысить производительность и улучшить оффлайн-опыт пользователей без значительных изменений структуры проекта.


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

  1. Сервис-воркер как отдельный модуль

    В большинстве UI-фреймворков рекомендуется держать сервис-воркер отдельно от основной логики приложения. Это позволяет:

    • Избежать конфликтов с системой сборки фреймворка (Webpack, Vite, Angular CLI).
    • Легко подключать Workbox через его API (workbox-core, workbox-routing, workbox-strategies) в модульной структуре.

    Пример подключения сервис-воркера в проекте на React:

    // service-worker.js
    import { precacheAndRoute } from 'workbox-precaching';
    import { registerRoute } from 'workbox-routing';
    import { StaleWhileRevalidate } from 'workbox-strategies';
    
    precacheAndRoute(self.__WB_MANIFEST);
    
    registerRoute(
      ({ request }) => request.destination === 'script' || request.destination === 'style',
      new StaleWhileRevalidate()
    );

    После этого сервис-воркер регистрируется в точке входа приложения:

    if ('serviceWorker' in navigator) {
      window.addEventListener('load', () => {
        navigator.serviceWorker.register('/service-worker.js');
      });
    }

Кэширование компонентов и статических ресурсов

UI-фреймворки активно используют модульную структуру с компонентами. Для улучшения производительности важно кэшировать не только статические файлы, но и ресурсы, используемые компонентами, такие как:

  • CSS и JS-файлы компонентов
  • Изображения и шрифты
  • API-запросы, от которых зависит рендеринг

Workbox предоставляет несколько стратегий кэширования, наиболее часто применяемых в контексте UI-фреймворков:

  • Cache First — для редко изменяющихся ресурсов (например, шрифтов и изображений).
  • Stale While Revalidate — для JS и CSS компонентов, позволяя быстро отображать старую версию и обновлять кэш на фоне.
  • Network First — для данных API, где актуальность информации критична.

Пример кэширования изображений в Vue-приложении:

registerRoute(
  ({ request }) => request.destination === 'image',
  new CacheFirst({
    cacheName: 'images-cache',
    plugins: [
      new ExpirationPlugin({
        maxEntries: 50,
        maxAgeSeconds: 30 * 24 * 60 * 60, // 30 дней
      }),
    ],
  })
);

Интеграция с роутером

Современные SPA используют роутеры (React Router, Vue Router, Angular Router). Workbox позволяет обрабатывать навигационные запросы и отдавать основной HTML для оффлайн-доступа, обеспечивая корректный переход между страницами.

Пример для React Router:

registerRoute(
  ({ request }) => request.mode === 'navigate',
  new NetworkFirst({
    cacheName: 'html-cache',
  })
);

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


Управление версиями и обновлениями компонентов

UI-фреймворки часто пересобирают бандлы при каждой сборке. Для предотвращения проблем с устаревшими файлами нужно использовать превентивное управление кэшем:

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

Пример уведомления в Angular:

import { BroadcastUpdatePlugin } from 'workbox-broadcast-update';

registerRoute(
  ({ request }) => request.destination === 'script',
  new StaleWhileRevalidate({
    plugins: [new BroadcastUpdatePlugin()],
  })
);

navigator.serviceWorker.addEventListener('message', (event) => {
  if (event.data.type === 'CACHE_UPDATED') {
    console.log('Обновлённый ресурс:', event.data.updatedURL);
  }
});

Оптимизация для сборщиков и фреймворков

  1. Webpack / Vite — использовать плагины workbox-webpack-plugin или vite-plugin-workbox, чтобы автоматически генерировать манифест для precache.
  2. Angular CLI — Angular Service Worker интегрирован с Workbox-подобными стратегиями через ngsw-config.json.
  3. Tree-shaking — импортировать только необходимые модули (workbox-routing, workbox-strategies) для уменьшения размера бандла.

Рекомендации по структуре проекта

  • service-worker.js в корне проекта для корректного контроля всех URL.
  • workbox-config.js или соответствующий плагин для генерации манифеста.
  • Разделение стратегий кэширования по типу ресурсов: JS/CSS, изображения, API, навигация.
  • Регулярная очистка старых кэшей через ExpirationPlugin.

Совместная работа с состоянием приложения

Некоторые UI-фреймворки используют глобальные состояния (Redux, Vuex, NgRx). Workbox позволяет кэшировать API-запросы, данные которых обновляют состояние:

  • Сохранять результат запроса в IndexedDB или кэше.
  • Использовать стратегию NetworkFirst с fallback на кэш.
  • Обновлять состояние приложения после успешного обновления данных.

Пример для Redux:

registerRoute(
  ({ url }) => url.pathname.startsWith('/api/data'),
  new NetworkFirst({
    cacheName: 'api-data-cache',
    plugins: [
      {
        cacheDidUpdate: async ({ cacheName, request }) => {
          const response = await caches.match(request);
          const data = await response.json();
          store.dispatch({ type: 'UPDATE_DATA', payload: data });
        },
      },
    ],
  })
);