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

Урок объясняет фоновую синхронизацию: как отложить отправку данных до восстановления сети.

Background Sync — механизм, который позволяет отложить сетевое действие (например, отправку сообщения) и автоматически выполнить его, когда связь восстановится.

Какую проблему решает

Представьте: пользователь в офлайне написал сообщение и нажал «Отправить». Без фоновой синхронизации запрос упадёт, и сообщение потеряется (или пользователю придётся жать кнопку снова, когда появится сеть). Background Sync решает это: вы регистрируете «задачу синхронизации», и браузер сам выполнит её, как только связь вернётся — даже если пользователь уже закрыл вкладку.

Регистрация задачи

Со стороны страницы регистрируем синхронизацию через объект регистрации Service Worker:

const reg = await navigator.serviceWorker.ready;
await reg.sync.register('send-messages');

Перед этим обычно сохраняют данные (сообщение) в IndexedDB, чтобы Service Worker мог их достать, когда настанет время отправки.

Обработка sync в Service Worker

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

async function sendPendingMessages() {
  // достать сообщения из IndexedDB и отправить на сервер
  // если упало — выбросить ошибку, браузер повторит позже
}

Метка (tag) 'send-messages' связывает регистрацию и обработчик. Если отправка не удалась (ошибка в Promise), браузер повторит синхронизацию позже сам, с растущими интервалами.

Как работает под капотом отложенность

Когда вы вызываете sync.register, браузер запоминает задачу. Если сеть есть — он выполнит её почти сразу. Если сети нет — задача «висит» и ждёт. Как только браузер обнаруживает восстановление связи, он будит Service Worker событием sync с вашим тегом — независимо от того, открыто ли приложение. Service Worker достаёт отложенные данные (обычно из IndexedDB) и отправляет их. Если снова неудача — браузер повторит попытку.

офлайн: register('send-messages') --> задача ждёт
сеть вернулась --> браузер будит SW --> событие sync --> отправка
ошибка --> браузер повторит позже

Periodic Background Sync

Есть родственный, более новый API — Periodic Background Sync: он позволяет периодически обновлять контент в фоне (например, подгружать свежие новости раз в сутки), даже когда приложение закрыто. Поддержка ограничена и обычно требует установленного PWA и «доверия» браузера к сайту.

Ограничения

  • Поддержка Background Sync есть не во всех браузерах (в первую очередь Chromium).
  • Браузер сам решает, когда выполнить задачу, — точное время не гарантировано.
  • На iOS поддержка отсутствует — нужен запасной план (повтор при следующем открытии).

Частые ошибки

  • Не сохранять данные перед sync. Service Worker не получит, что отправлять; храните в IndexedDB.
  • Не выбрасывать ошибку при неудаче. Тогда браузер посчитает задачу выполненной и не повторит.
  • Рассчитывать на Background Sync на iOS. Его там нет — предусмотрите fallback.

Итоги

  • Background Sync откладывает сетевое действие и выполняет его при восстановлении связи.
  • Данные сохраняют в IndexedDB, затем регистрируют sync.register(tag).
  • Service Worker ловит событие sync по тегу и отправляет; при ошибке браузер повторит.
  • Поддержка ограничена (нет на iOS) — нужен запасной сценарий.
Проверьте себя
1. Какую задачу решает Background Sync?
AУскоряет загрузку картинок
BОткладывает сетевое действие и выполняет его, когда связь восстановится, даже если вкладка закрыта
CКеширует CSS
DПоказывает уведомления
2. Почему важно выбросить ошибку в обработчике sync, если отправка не удалась?
AЧтобы залогировать
BЧтобы браузер не считал задачу выполненной и повторил синхронизацию позже
CЧтобы удалить кеш
DЭто ни на что не влияет