Фоновая синхронизация и Background Sync API

Background Sync API — это современный инструмент в браузерах, который позволяет веб-приложениям отложенно выполнять сетевые запросы, когда устройство снова оказывается онлайн. Основная цель API — улучшение устойчивости приложений к временной потере интернет-соединения. С его помощью можно гарантировать отправку данных на сервер даже при нестабильной сети, сохраняя их в очереди до момента восстановления соединения.

Ключевой объект для работы с API — Service Worker. Он регистрируется для обработки событий синхронизации, позволяя веб-приложению работать независимо от состояния сети. Service Worker получает событие sync и выполняет задачи, которые были отложены ранее.

self.addEventListener('sync', function(event) {
  if (event.tag === 'send-comments') {
    event.waitUntil(sendCommentsToServer());
  }
});

Здесь event.tag используется для идентификации конкретной задачи синхронизации. Метод waitUntil гарантирует, что Service Worker не завершит выполнение, пока промис, возвращаемый функцией sendCommentsToServer, не будет выполнен.


Регистрация синхронизации

Для регистрации задачи синхронизации используется метод sync.register в контексте Service Worker. Простейший пример выглядит так:

navigator.serviceWorker.ready.then(function(swRegistration) {
  return swRegistration.sync.register('send-comments');
});
  • navigator.serviceWorker.ready возвращает промис, который разрешается, когда Service Worker полностью активирован.
  • sync.register принимает строку — уникальный тег задачи, который позже позволяет обработчику идентифицировать, какая именно операция должна быть выполнена.

Очередь задач и отложенная отправка

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

Пример очереди сообщений:

function storeComment(comment) {
  const dbPromise = idb.openDB('comments-store', 1, {
    upgrade(db) {
      db.createObjectStore('comments', { keyPath: 'id', autoIncrement: true });
    }
  });

  dbPromise.then(db => {
    const tx = db.transaction('comments', 'readwrite');
    tx.objectStore('comments').add(comment);
    return tx.done;
  });
}

Здесь создается объектное хранилище comments, куда помещаются данные, пока сеть недоступна. После восстановления интернет-соединения Service Worker получает событие sync и выполняет функцию отправки всех сохраненных комментариев на сервер:

async function sendCommentsToServer() {
  const db = await idb.openDB('comments-store', 1);
  const comments = await db.getAll('comments');

  await Promise.all(comments.map(comment =>
    fetch('/api/comments', {
      method: 'POST',
      body: JSON.stringify(comment),
      headers: { 'Content-Type': 'application/json' }
    }).then(() => db.delete('comments', comment.id))
  ));
}
  • getAll извлекает все накопленные записи.
  • Promise.all выполняет отправку параллельно.
  • После успешной отправки запись удаляется из базы, предотвращая повторную отправку.

Параметры и ограничения

Background Sync имеет несколько особенностей, которые важно учитывать:

  1. Теги задач должны быть уникальными. Повторная регистрация синхронизации с тем же тегом объединяется в одно событие.
  2. Ограничения браузера. Некоторые старые версии не поддерживают API или требуют HTTPS.
  3. Временные ограничения. Service Worker может быть прерван системой, если задача выполняется слишком долго. Рекомендуется использовать короткие, атомарные операции.
  4. Повторная регистрация при сбое. В случае ошибки промис можно повторно зарегистрировать, чтобы задача была выполнена позже.

Связь с offline-first стратегиями

Background Sync идеально интегрируется с паттерном offline-first. Вместо того чтобы блокировать пользовательский интерфейс ожиданием сети, данные сохраняются локально, а синхронизация происходит в фоновом режиме. Это обеспечивает:

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

Применение с Push API

Background Sync часто комбинируют с Push API. Например, можно получать уведомления о новых задачах, сохранять их локально и использовать синхронизацию для отправки пользовательских ответов. Такой подход создает полностью автономное и интерактивное веб-приложение, способное работать даже при отсутствии сети, а затем корректно синхронизировать состояние при восстановлении соединения.


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

  • Разделять задачи на небольшие, атомарные операции.
  • Использовать IndexedDB для хранения временных данных.
  • Обрабатывать ошибки и предусматривать повторные попытки.
  • Минимизировать объем сетевых запросов за один раз для экономии батареи и ресурсов устройства.
  • Следить за поддержкой браузеров и предоставлять fallback для устаревших платформ.

Background Sync API обеспечивает надежный механизм для фоновой доставки данных, упрощает реализацию offline-first приложений и повышает устойчивость веб-приложений к проблемам с сетью.