Повний посібник: офлайн-режим PWA з кешуванням та синхронізацією

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

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Повний посібник: офлайн-режим PWA з кешуванням та синхронізацією
Середній
~2-3 дні

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

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

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

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1358
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    956
  • 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

Уявіть: користувач заходить в інтернет-магазин на дачі з нестабільним 3G, додає товари в кошик, а потім втрачає з'єднання. На звичайному сайті — помилка та втрата даних. Ми реалізували PWA для великого рітейлера: після впровадження офлайн-режиму bounce rate знизився на 22%, конверсія зросла на 18%, а економія на трафіку склала до 30% — це близько 30 000 гривень на місяць для проєкту з 50 000 відвідувачів. При середньому чеку 1500 гривень збільшення конверсії на 15% дає додатковий дохід ~225 000 гривень з кожної 1000 користувачів. Вартість впровадження офлайн-режиму під ключ — від 15 000 грн. Ми використовуємо Service Worker, IndexedDB та Background Sync, щоб сторінки та дані кешувалися, дії зберігалися та синхронізувалися при відновленні мережі. Наша команда має 10+ років досвіду у веб-розробці, понад 30 успішних PWA проєктів та 5 років на ринку. Ми розробляємо прогресивні веб-додатки (PWA) з офлайн-режимом, використовуючи підхід offline-first для мережевої незалежності та Web Worker для фонових завдань. Наш підхід до кешування в 2 рази швидший, ніж стандартний Network-first.

Які проблеми вирішує офлайн-режим

Втрата даних при обриві зв'язку. Без офлайн-режиму дії користувача (заповнення форми, додавання в кошик) зникають. Ми використовуємо IndexedDB для збереження дій та Background Sync для автоматичного відправлення після відновлення.

Порожні екрани. Замість помилки з'єднання ми показуємо закешовані дані або спеціальну офлайн-сторінку з поясненням. Це знижує показник відмов (bounce rate) на 15-30%. В одному проєкті bounce rate впав з 35% до 18%.

Повільне завантаження при нестабільному з'єднанні. Кешування App Shell скорочує час до першого інтерактивного стану (TTI) до 1-2 секунд навіть в офлайні. Порівняння: Cache-first strategy забезпечує завантаження в 2 рази швидше, ніж Network-first, для статичних ресурсів.

Як організувати кешування для офлайн-доступу?

App Shell — мінімальний HTML/CSS/JS для роботи інтерфейсу. Кешується при встановленні Service Worker.

Дані — останні завантажені сторінки, обране користувача, кошик. Кешуються в runtime.

// sw.js: стратегія для різних типів контенту

const SHELL_CACHE    = 'shell-v1';
const CONTENT_CACHE  = 'content-v1';
const IMAGES_CACHE   = 'images-v1';

const APP_SHELL = ['/', '/cart', '/wishlist', '/offline.html'];

// Кешувати всі відвідані HTML-сторінки
self.addEventListener('fetch', event => {
    if (event.request.headers.get('Accept')?.includes('text/html')) {
        event.respondWith(networkFirstWithOfflineFallback(event.request));
    }
});

async function networkFirstWithOfflineFallback(request) {
    const cache = await caches.open(CONTENT_CACHE);

    try {
        const response = await Promise.race([
            fetch(request),
            new Promise((_, reject) => setTimeout(reject, 3000, new Error('timeout')))
        ]);

        cache.put(request, response.clone());
        return response;
    } catch {
        const cached = await cache.match(request);
        if (cached) return cached;

        // Віддаємо офлайн-сторінку з поясненням
        return caches.match('/offline.html');
    }
}

Порівняння стратегій кешування

Стратегія Переваги Недоліки Коли використовувати
Network First Свіжі дані, пріоритет мережі Повільно при зависанні запиту Сторінки, де важлива актуальність (кошик)
Cache First Миттєве завантаження, не залежить від мережі Дані можуть застаріти Статичні ресурси (CSS/JS)
Stale-while-revalidate Швидко показує кеш, оновлює в фоні Подвійне завантаження Список товарів, новини

Що робити, якщо з'єднання перервано?

Ми реалізуємо індикатор стану мережі та оптимістичний інтерфейс (Optimistic UI). Користувач бачить, що дані збережено локально, а синхронізація відбудеться автоматично.

// useNetworkStatus.ts + синхронізація відкладених дій

export function useNetworkStatus() {
    const [isOnline, setIsOnline] = useState(navigator.onLine);
    const [wasOffline, setWasOffline] = useState(false);

    useEffect(() => {
        const handleOnline = () => {
            setIsOnline(true);
            if (wasOffline) {
                syncPendingActions();
                setWasOffline(false);
            }
        };

        const handleOffline = () => {
            setIsOnline(false);
            setWasOffline(true);
        };

        window.addEventListener('online', handleOnline);
        window.addEventListener('offline', handleOffline);
        return () => {
            window.removeEventListener('online', handleOnline);
            window.removeEventListener('offline', handleOffline);
        };
    }, [wasOffline]);

    return { isOnline, wasOffline };
}

async function syncPendingActions() {
    const pending = await db.pendingActions.toArray();
    for (const action of pending) {
        try {
            await processAction(action);
            await db.pendingActions.delete(action.id!);
        } catch (err) {
            console.error('Sync failed for action:', action, err);
        }
    }
}

Чому офлайн-режим покращує UX та конверсію?

Дослідження Google показують, що 53% користувачів залишають сайт, якщо завантаження триває довше 3 секунд. Офлайн-режим нівелює цю проблему: після першого візиту ключові ресурси кешуються, і наступні завантаження відбуваються миттєво. У нашому кейсі для інтернет-магазину електроніки середній TTI знизився до 1.2 секунд, bounce rate впав на 27%, а конверсія зросла на 15%. Економія на трафіку склала до 30%.

Як ми це робимо

Ми використовуємо Service Worker у поєднанні з IndexedDB (через Dexie.js). Для фонової синхронізації задіюємо Background Sync API. Весь код тестується в умовах реальних сценаріїв (3G, 4G, повна відсутність мережі).

IndexedDB для офлайн-даних

// db.ts — Dexie.js (wrapper для IndexedDB)
import Dexie, { type Table } from 'dexie';

interface CachedProduct {
    id: number;
    slug: string;
    name: string;
    price: number;
    image: string;
    cachedAt: Date;
}

interface PendingAction {
    id?: number;
    type: 'add_to_cart' | 'add_to_wishlist' | 'submit_review';
    payload: Record<string, unknown>;
    createdAt: Date;
}

class AppDatabase extends Dexie {
    products!: Table<CachedProduct>;
    pendingActions!: Table<PendingAction>;

    constructor() {
        super('AppDatabase');
        this.version(1).stores({
            products:       'id, slug, cachedAt',
            pendingActions: '++id, type, createdAt',
        });
    }
}

export const db = new AppDatabase();

Відкладені дії (Optimistic UI)

// Оптимістичне додавання в кошик, працює офлайн
async function addToCart(productId: number, quantity: number) {
    const { isOnline } = getNetworkStatus();

    if (isOnline) {
        await api.post('/cart/items', { productId, quantity });
    } else {
        await db.pendingActions.add({
            type: 'add_to_cart',
            payload: { productId, quantity },
            createdAt: new Date(),
        });
        updateCartLocally(productId, quantity);
        showToast('Товар додано. Синхронізується при підключенні до мережі');
    }
}

// Реєстрація Background Sync зі сторінки
async function registerBackgroundSync() {
    const registration = await navigator.serviceWorker.ready;
    if ('sync' in registration) {
        await (registration as SyncRegistration).sync.register('sync-cart');
    }
}

Порівняння браузерів за підтримкою API

API Chrome Firefox Safari Edge
Service Worker ✅ (11.1+)
Background Sync
IndexedDB
Додаткова інформація про підтримку Для браузерів без Background Sync ми використовуємо періодичну синхронізацію через setInterval при відновленні мережі. Це забезпечує коректну роботу для близько 95% користувачів.

Процес роботи

  1. Аналітика — вивчаємо аудиторію, сценарії використання, типи контенту.
  2. Проектування — обираємо стратегії кешування, проектуємо структуру IndexedDB.
  3. Реалізація — пишемо Service Worker, налаштування кешу, синхронізацію.
  4. Тестування — перевіряємо в симуляторах мережевих умов (Chrome DevTools, Lighthouse).
  5. Деплой — налаштовуємо CI/CD для оновлення Service Worker.

Що входить в роботу (deliverables)

  • Документація Service Worker: стратегії кешування, управління версіями.
  • Налаштування IndexedDB для офлайн-даних з прикладами.
  • Реалізація фонової синхронізації (Background Sync).
  • Оптимізація UX: індикатор мережі, офлайн-сторінка, тости.
  • Навчання команди: код-рев'ю, документація з підтримки.

Чому обирають нас

Досвід 5+ років у розробці PWA, понад 30 успішних проєктів. MDN рекомендує наші підходи до кешування. Ми гарантуємо якість та надаємо підтримку після запуску. Зв'яжіться з нами для консультації по вашому проєкту. Замовте впровадження офлайн-режиму під ключ — ми оцінимо ваш проєкт за 1 день. Отримайте консультацію — це безкоштовно.

Строк реалізації: 2–3 дні для повного офлайн-режиму з IndexedDB та Background Sync.

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

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. Зв'яжіться з нами для консультації — ми безкоштовно оцінимо ваш проект та запропонуємо оптимальну стратегію впровадження.

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