PWA офлайн: кэширование, синхронизация и UX для вашего проекта

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

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

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
PWA офлайн: кэширование, синхронизация и UX для вашего проекта
Средний
~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 пользователей. Мы используем Service Worker, IndexedDB и Background Sync, чтобы страницы и данные кэшировались, действия сохранялись и синхронизировались при восстановлении сети. За 10+ лет работы мы внедрили такие решения для десятков проектов, гарантируя надёжность и удобство пользователей.

Какие проблемы решает офлайн-режим

Потеря данных при обрыве связи. Без офлайн-режима действия пользователя (заполнение формы, добавление в корзину) пропадают. Мы используем 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. Свяжитесь с нами для консультации — мы бесплатно оценим ваш проект и предложим оптимальную стратегию внедрения.

Ссылки для углублённого изучения