Синхронизация состояния при восстановлении соединения

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

Стратегии обработки офлайн-запросов

Workbox предлагает несколько подходов к организации запросов при отсутствии соединения:

  1. Background Sync Модуль workbox-background-sync позволяет откладывать отправку запросов до восстановления сети. Создается очередь, куда помещаются все неудачные запросы, и после появления соединения они автоматически повторяются.

    Пример создания очереди:

    import { Queue } from 'workbox-background-sync';
    
    const myQueue = new Queue('requestQueue', {
      maxRetentionTime: 24 * 60 // время хранения запросов в минутах
    });
    
    self.addEventListener('fetch', (event) => {
      if (event.request.method === 'POST') {
        event.respondWith(
          fetch(event.request.clone()).catch((err) => {
            return myQueue.pushRequest({ request: event.request });
          })
        );
      }
    });

    Ключевые моменты:

    • maxRetentionTime задает максимальное время хранения запроса в очереди.
    • Клонирование запроса необходимо, потому что fetch и pushRequest используют тело запроса, которое может быть прочитано только один раз.
  2. Автоматическая повторная отправка Workbox позволяет настраивать автоматическое повторение запросов с экспоненциальной задержкой, что особенно полезно для REST API с критичными POST-запросами.

    import { NetworkOnly } from 'workbox-strategies';
    import { registerRoute } from 'workbox-routing';
    
    registerRoute(
      /\/api\/.*\/update/,
      new NetworkOnly({
        plugins: [
          myQueue
        ]
      }),
      'POST'
    );

    Этот подход комбинирует стратегию NetworkOnly с очередью Background Sync, обеспечивая безопасную доставку данных после восстановления сети.

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

Для корректной синхронизации состояния важно правильно организовать кэширование. Workbox позволяет:

  • Стратегия StaleWhileRevalidate – мгновенная отдача старых данных с одновременной загрузкой свежих. Это гарантирует, что пользователь видит информацию без задержек, а Service Worker обновляет кэш для будущих обращений.

  • Стратегия CacheFirst с ограничениями – полезна для медиа-ресурсов и больших файлов. Параметры maxEntries и maxAgeSeconds позволяют контролировать размер кэша и срок жизни данных.

Пример:

import { CacheFirst } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';

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

Обработка конфликтов данных

Когда офлайн-запросы накапливаются, а серверная версия данных изменяется, возникает проблема конфликтов. Для минимизации рисков используют:

  • Идентификаторы версий данных – каждый объект снабжается полем version или timestamp. При синхронизации Service Worker проверяет актуальность версии перед отправкой запроса.
  • Локальная очередь с приоритетами – более важные изменения отправляются первыми, менее критичные откладываются.
  • Обратная проверка состояния – после восстановления соединения клиент получает актуальный набор данных с сервера и сравнивает с локальными изменениями, разрешая конфликты.

Логирование и уведомления

Workbox предоставляет события для отслеживания состояния очередей:

myQueue.on('sync', ({ queue }) => {
  console.log(`${queue.name} синхронизирована`);
});

myQueue.on('requestfailure', ({ request }) => {
  console.error(`Не удалось отправить запрос: ${request.url}`);
});

Это позволяет вести журнал операций и информировать интерфейс приложения о статусе синхронизации.

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

  • Разделять критичные и некритичные запросы, чтобы минимизировать нагрузку на сеть при восстановлении соединения.
  • Использовать индексацию в IndexedDB для временного хранения данных офлайн, чтобы очереди не теряли информацию при закрытии браузера.
  • Настраивать обработку ошибок на уровне Service Worker, чтобы исключить бесконечные циклы повторной отправки.
  • При сложной логике синхронизации объединять Workbox с idb или аналогичной библиотекой для удобной работы с локальными хранилищами.

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