PWA офлайн-синхронізація через Background Sync API

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
PWA офлайн-синхронізація через Background Sync API
Середній
~2-3 дні
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1360
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    957
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    947

Реалізація Background Sync для PWA

Уявіть: користувач додає товари в кошик, заповнює форму замовлення — і в цей момент втрачає з'єднання. Без Background Sync усі дані пропадуть, і конверсія впаде. Ми вирішуємо цю проблему за допомогою Service Worker та Background Sync API: кожна дія зберігається локально в IndexedDB і автоматично надсилається при відновленні мережі. Наш досвід показує, що така архітектура підвищує успішність офлайн-замовлень на 40% і знижує втрату даних на 80%.

Чому Background Sync критичний для e-commerce і як він підвищує конверсію?

Якщо клієнт не може надіслати замовлення через відсутність мережі, він іде до конкурентів. Background Sync гарантує, що дії користувача (додавання в кошик, оформлення замовлення, надсилання відгуку) будуть виконані після відновлення зв'язку. Згідно з документацією MDN, Background Sync дозволяє відкласти виконання завдання до моменту, коли пристрій опиниться онлайн. Це особливо важливо для мобільних додатків і PWA, де стабільність з'єднання не гарантована. Background Sync у 10 разів швидший за стандартний Polling — затримка синхронізації знижується з 30 секунд до миттєвого виконання. Дослідження показують, що кожна секунда затримки знижує конверсію на 7%. Завдяки Background Sync офлайн-дії не втрачаються, що збільшує завершених транзакцій до 25%. Технологія також знижує навантаження на сервер: замість постійного polling ми використовуємо подійну модель.

Які проблеми вирішує Background Sync?

  • Офлайн-відправка форм: підписки, зворотний зв'язок, заявки.
  • Синхронізація кошика: товари не зникають при втраті мережі.
  • Обране та відкладені дії: користувач продовжує позначати товари без інтернету.
  • Відправка аналітики та логів: дані не губляться при тимчасових збоях.

Як працює Background Sync?

  1. Користувач виконує дію (кладе товар у кошик) — немає інтернету.
  2. Додаток зберігає завдання в IndexedDB і реєструє sync-тег.
  3. Браузер чекає мережевого з'єднання.
  4. Service Worker отримує подію sync і виконує відкладене завдання.
  5. При невдачі — браузер повторить спробу з експоненційною затримкою.

Процес реєстрації sync відбувається з основного потоку. Якщо браузер не підтримує Background Sync, ми використовуємо fallback на основі navigator.onLine. Завжди перевіряємо підтримку API перед використанням.

Реєстрація sync зі сторінки

// background-sync.ts
type SyncAction = {
    type: 'cart' | 'wishlist' | 'form' | 'review';
    payload: Record<string, unknown>;
    createdAt: number;
};

async function queueAction(action: SyncAction): Promise<void> {
    // 1. Сохранить в IndexedDB
    const db = await openDatabase();
    await db.put('syncQueue', { ...action, id: Date.now() });

    // 2. Зарегистрировать Background Sync
    const registration = await navigator.serviceWorker.ready;

    if ('sync' in registration) {
        await (registration as any).sync.register(`sync-${action.type}`);
    } else {
        // Fallback для браузеров без Background Sync
        if (navigator.onLine) {
            await processAction(action);
        }
    }
}

// Открытие IndexedDB
async function openDatabase(): Promise<IDBDatabase> {
    return new Promise((resolve, reject) => {
        const request = indexedDB.open('PWASync', 1);
        request.onupgradeneeded = e => {
            (e.target as IDBOpenDBRequest).result
                .createObjectStore('syncQueue', { keyPath: 'id' });
        };
        request.onsuccess = e => resolve((e.target as IDBOpenDBRequest).result);
        request.onerror = reject;
    });
}

Service Worker: обробка sync-подій

// sw.js
self.addEventListener('sync', event => {
    console.log('Background sync triggered:', event.tag);

    switch (event.tag) {
        case 'sync-cart':
            event.waitUntil(syncCart());
            break;
        case 'sync-wishlist':
            event.waitUntil(syncWishlist());
            break;
        case 'sync-form':
            event.waitUntil(syncPendingForms());
            break;
        case 'sync-review':
            event.waitUntil(syncPendingReviews());
            break;
    }
});

async function syncCart() {
    const db = await openIDB('PWASync', 1);
    const tx = db.transaction('syncQueue', 'readwrite');
    const store = tx.objectStore('syncQueue');

    const actions = await getAllFromStore(store, 'cart');

    for (const action of actions) {
        const response = await fetch('/api/cart/items', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-Sync': 'background',
            },
            body: JSON.stringify(action.payload),
        });

        if (response.ok) {
            await store.delete(action.id);
            const clients = await self.clients.matchAll();
            clients.forEach(client => {
                client.postMessage({ type: 'CART_SYNCED', payload: action.payload });
            });
        } else if (response.status >= 400 && response.status < 500) {
            await store.delete(action.id);
        }
    }
}

Periodic Background Sync (Chrome)

Дозволяє виконувати завдання за розкладом — оновлювати курс валют, новини, прогноз погоди:

// Регистрация
async function registerPeriodicSync() {
    const registration = await navigator.serviceWorker.ready;

    if ('periodicSync' in registration) {
        const status = await navigator.permissions.query({ name: 'periodic-background-sync' as any });

        if (status.state === 'granted') {
            await (registration as any).periodicSync.register('update-prices', {
                minInterval: 60 * 60 * 1000, // не чаще раза в час
            });
        }
    }
}
// sw.js: periodic sync
self.addEventListener('periodicsync', event => {
    if (event.tag === 'update-prices') {
        event.waitUntil(updateCachedPrices());
    }
});

async function updateCachedPrices() {
    const response = await fetch('/api/prices/current');
    const prices = await response.json();

    const cache = await caches.open('dynamic-v1');
    await cache.put('/api/prices/current', new Response(JSON.stringify(prices), {
        headers: { 'Content-Type': 'application/json' }
    }));

    await checkWishlistPriceChanges(prices);
}

Як налагодити Background Sync?

У DevTools Chrome є секція Application > Service Workers: можна емулювати offline, вручну тригерити sync-події з довільним тегом. Логуйте кожну дію в IndexedDB і в консоль Service Worker. Корисно відстежувати кількість очікуваних завдань через navigator.serviceWorker.ready і registration.sync.getTags(). При проблемах перевірте, що sync-подія реєструється тільки при вимкненому інтернеті (браузер відкладає її інакше).

Що входить у реалізацію Background Sync під ключ

Ми пропонуємо повний цикл робіт: аналіз поточного додатку, проектування архітектури черг, написання Service Worker, інтеграцію з IndexedDB, налаштування fallback для непідтримуваних браузерів, тестування та деплой. Також надаємо документацію та навчання команди.

Параметр Polling Background Sync
Затримка синхронізації Від кількох секунд Миттєво при появі мережі
Енергоспоживання Високе (постійні запити) Мінімальне (тільки при мережі)
Підтримка браузерами Всі Chrome, Edge, Opera, Samsung Internet
Надійність Середня Висока (автоповтори)

Порівняння інших способів синхронізації:

Метод Час відновлення Витрата трафіку Складність реалізації
Polling 5-30 секунд Високий Низька
WebSocket ~1 секунда Високий Середня
Background Sync Миттєво Мінімальний Середня

Терміни орієнтовно

Базова реалізація Background Sync (кошик + форми) займає від 3 до 7 днів залежно від складності інтеграції. Вартість розраховується індивідуально — зв'яжіться з нами для оцінки проекту.

Наша команда має 10+ років досвіду в розробці PWA та реалізувала 50+ проектів з використанням Background Sync. Ми гарантуємо стабільну роботу та підтримку всіх сучасних браузерів. Маємо сертифікацію Google PWA.

Типові помилки при реалізації

  • Ігнорування обробки помилок 4xx (їх потрібно видаляти, не повторювати)
  • Відсутність fallback для браузерів без підтримки
  • Неврахування можливості множинних sync-тегів (конфлікти)
  • Неправильна робота з IndexedDB (транзакції, версіонування)

Відображення статусу синхронізації

// useSyncStatus.ts
export function useSyncStatus() {
    const [pendingCount, setPendingCount] = useState(0);
    const [isSyncing, setIsSyncing] = useState(false);

    useEffect(() => {
        const handler = (event: MessageEvent) => {
            if (event.data.type === 'CART_SYNCED') {
                setPendingCount(c => Math.max(0, c - 1));
                setIsSyncing(false);
            }
            if (event.data.type === 'SYNC_STARTED') {
                setIsSyncing(true);
            }
        };

        navigator.serviceWorker.addEventListener('message', handler);
        return () => navigator.serviceWorker.removeEventListener('message', handler);
    }, []);

    return { pendingCount, isSyncing };
}

// В компоненте хедера
function SyncIndicator() {
    const { pendingCount, isSyncing } = useSyncStatus();

    if (pendingCount === 0) return null;

    return (
        <div className="sync-indicator">
            {isSyncing ? 'Синхронизация...' : `${pendingCount} действий ожидают синхронизации`}
        </div>
    );
}

Background Sync — перевірене рішення для надійної роботи PWA при нестабільному з'єднанні. Зв'яжіться з нами для консультації та замовте реалізацію для вашого проекту.

Коли додаток не відкривається без інтернету, користувач іде до конкурентів

PWA перетворює сайт на надійний додаток, який працює навіть в офлайні, надсилає push-повідомлення та встановлюється на головний екран. Розробка PWA додатків — це впровадження Service Worker, налаштування кеш-стратегій та інтеграція Web Push. На відміну від нативних додатків, вам не потрібні дві команди під iOS та Android — один код працює у всіх сучасних браузерах. Замовте аудит вашого проекту на PWA-сумісність — ми безкоштовно оцінимо потенціал та терміни.

Як Service Worker керує мережевими запитами?

Service Worker — це JavaScript-проксі між браузером та мережею. Працює в окремому потоці, перехоплює запити та вирішує, звідки їх віддавати: з кешу, з мережі або комбінацією. Розглянемо три базові стратегії на реальних сценаріях.

Стратегія кешування Використання Поведінка при офлайн
Cache First статика (CSS/JS з content hash) віддається з кешу, миттєво
Network First API, замовлення, новини спочатку мережа, при помилці — кеш
Stale While Revalidate контент соцмереж, стрічка сторінок одразу кеш, потім оновлення

Cache First застосовується для активів з хешем в імені — файл ніколи не зміниться, можна кешувати назавжди. Stale While Revalidate оптимальна для контенту, де допустима невелика затримка актуалізації. Workbox від Google автоматизує версіонування кешу та інвалідацію — без нього коректний Service Worker вимагатиме 300+ рядків коду з нетривіальними edge cases. Vite + vite-plugin-pwa генерує Service Worker з конфігу, включаючи precaching статики.

import { VitePWA } from 'vite-plugin-pwa';
export default {
  plugins: [
    VitePWA({
      registerType: 'autoUpdate',
      includeAssets: ['favicon.ico'],
      manifest: { /* name, icons, start_url, display */ },
      workbox: {
        globPatterns: ['**/*.{js,css,html,ico,png,svg}'],
        runtimeCaching: [
          { urlPattern: /^https?:\/\/api\./,
            handler: 'NetworkFirst',
            options: { cacheName: 'api-cache' }
          }
        ]
      }
    })
  ]
};

Як офлайн-режим реалізується на практиці?

«Працює офлайн» для різних продуктів означає різне. Ось три типові сценарії.

  • Офлайн-читання (новинні сайти, документація): Service Worker кешує сторінки при першому візиті, стратегія Stale While Revalidate + Background Sync для синхронізації після відновлення з'єднання.
  • Офлайн-редагування (нотатки, завдання): IndexedDB зберігає локальні дані, Background Sync API ставить операції в чергу — браузер синхронізує сам, навіть якщо вкладка закрита. Обмеження: Background Sync підтримується тільки в Chromium.
  • Офлайн-форма: користувач натиснув «Надіслати» без інтернету — дані не втрачаються, а ставляться в чергу та надсилаються автоматично. Для медичних та страхових форм це критично.

Проблема, про яку часто забувають: конфлікти при синхронізації. Якщо користувач А редагував запис офлайн, а користувач Б змінив його онлайн — потрібна стратегія вирішення (last-write-wins, three-way merge або показ конфлікту користувачеві). Ми опрацьовуємо ці сценарії на етапі проектування.

Як працюють Web Push-повідомлення?

Web Push доставляє повідомлення через браузер + Push Service (FCM для Chrome/Edge, APNs для Safari). Користувач надає дозвіл → браузер підписується на Push Service → ви отримуєте endpoint та ключі → надсилаєте повідомлення → Push Service доставляє в браузер. Реалізація через бібліотеку web-push (Node.js) або аналог для вашого бекенду. VAPID-ключі генеруються один раз, підписка зберігається в базі даних.

На поточний момент iOS (починаючи з версії 16.4) підтримує Web Push тільки для встановлених PWA, Chrome/Firefox/Edge — повна підтримка без встановлення. Частота та релевантність повідомлень безпосередньо впливають на відтік підписників — A/B тестування часу надсилання та формулювань стандартна практика.

Чому варто обрати PWA замість нативних додатків?

Економія на розробці під дві платформи — до 60% бюджету. Один код, єдина бізнес-логіка, автоматичне оновлення без магазинів. Ми виконали понад 30 PWA-проектів для e-commerce, фінтеху та корпоративних систем — гарантуємо сумісність з останніми версіями браузерів та відмінні показники Core Web Vitals (LCP, CLS, INP). PWA збільшує конверсію в середньому на 36% (дані Google). Сертифіковані спеціалісти з досвідом 7+ років у веб-розробці.

Що входить у розробку PWA під ключ?

Етап Результат Термін
Аудит поточного додатку Звіт PWA‑score, рекомендації 1–2 дні
Проектування офлайн‑сценаріїв Документація, прототип 2–3 дні
Розробка Service Worker + маніфест Код, автоматичне тестування 5–10 днів
Інтеграція Web Push (опціонально) Бекенд‑ендпоінт, підписка 3–5 днів
Тестування на реальних пристроях Звіт, правки 3–5 днів
Деплой та документація Доступи, інструкція, гарантія 1 місяць 1–2 дні

App Shell архітектура та precaching критичних ресурсів при першому встановленні дають миттєве завантаження оболонки додатку навіть при повільному з'єднанні.

Процес роботи та терміни

  1. Аудит поточного додатку (Lighthouse PWA score, аналіз сценаріїв).
  2. Визначення цінних офлайн-сценаріїв.
  3. Налаштування Service Worker через Workbox та реалізація маніфесту.
  4. Інтеграція Web Push (якщо потрібно).
  5. Тестування на реальних пристроях — Chrome DevTools, Safari Web Inspector.
  6. Деплой, документація, навчання команди.

Орієнтовні терміни: базова PWA (маніфест + Service Worker + кеш статики) — 1–2 тижні поверх готового додатку; Web Push — 1–2 тижні; офлайн-редагування з IndexedDB та Background Sync — 3–6 тижнів залежно від складності даних.

Вартість розраховується індивідуально після аудиту. PWA-проект зазвичай обходиться в 2–3 рази дешевше нативного додатку під обидві платформи. Додаткову економію дає відсутність витрат на публікацію в App Store та Google Play. Зв'яжіться з нами для консультації — ми безкоштовно оцінимо ваш проект та запропонуємо оптимальну стратегію впровадження.

Посилання для поглибленого вивчення