Реализация PWA (Progressive Web App) для сайта

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

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

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Реализация PWA (Progressive Web App) для сайта
Сложный
от 1 недели до 3 месяцев
Часто задаваемые вопросы

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

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1359
  • 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

Разработка Progressive Web App (PWA)

Сайт теряет до 40% трафика, если пользователь уходит из-за медленной загрузки? Или каждый второй посетитель не возвращается после первого визита? Мы помогаем внедрить PWA под ключ — это решение, которое сочетает скорость веба и возможности нативных приложений. PWA устанавливается на домашний экран, работает офлайн и может отправлять push-уведомления. За 2–4 дня вы получаете приложение, которое грузится в 2 раза быстрее на медленных соединениях. По данным Google, PWA увеличивают конверсию на 36% и снижают отказы на 15%. Средняя стоимость привлечения клиента (CAC) при этом существенно снижается, что экономит бюджет на рекламу.

Как PWA решает проблему офлайн-доступа?

Основная боль: пользователь теряет связь — сайт недоступен. Service Worker кэширует ключевые ресурсы (App Shell) и страницы. Даже при обрыве соединения человек видит интерфейс, а не ошибку. Мы используем три стратегии кэширования в зависимости от типа данных:

Стратегия Применение Поведение
Cache First Статика (CSS, JS, изображения) Отдаёт из кэша, обновляет фоном
Network First HTML-страницы Сначала сеть, при ошибке — кэш
Stale While Revalidate Изображения, API Мгновенно из кэша, потом обновляет

Web App Manifest — основа устанавливаемости

Для появления кнопки «Добавить на главный экран» требуется корректный манифест. Мы настраиваем все поля: name, short_name, icons в 8 размерах (включая maskable), screenshots для Android, shortcuts для быстрых действий. Пример манифеста:

{
    "name": "ТехноМагазин — купить электронику",
    "short_name": "ТехноМагазин",
    "description": "Смартфоны, ноутбуки, аксессуары с доставкой",
    "start_url": "/?source=pwa",
    "scope": "/",
    "display": "standalone",
    "orientation": "portrait-primary",
    "theme_color": "#1a73e8",
    "background_color": "#ffffff",
    "lang": "ru",
    "dir": "ltr",
    "icons": [
        { "src": "/icons/icon-72.png",   "sizes": "72x72",   "type": "image/png" },
        { "src": "/icons/icon-96.png",   "sizes": "96x96",   "type": "image/png" },
        { "src": "/icons/icon-128.png",  "sizes": "128x128", "type": "image/png" },
        { "src": "/icons/icon-144.png",  "sizes": "144x144", "type": "image/png" },
        { "src": "/icons/icon-152.png",  "sizes": "152x152", "type": "image/png" },
        { "src": "/icons/icon-192.png",  "sizes": "192x192", "type": "image/png", "purpose": "any maskable" },
        { "src": "/icons/icon-384.png",  "sizes": "384x384", "type": "image/png" },
        { "src": "/icons/icon-512.png",  "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }
    ],
    "screenshots": [
        {
            "src": "/screenshots/mobile-catalog.webp",
            "sizes": "390x844",
            "type": "image/webp",
            "form_factor": "narrow",
            "label": "Каталог товаров"
        }
    ],
    "shortcuts": [
        {
            "name": "Корзина",
            "url": "/cart",
            "icons": [{ "src": "/icons/cart-96.png", "sizes": "96x96" }]
        },
        {
            "name": "Избранное",
            "url": "/wishlist",
            "icons": [{ "src": "/icons/heart-96.png", "sizes": "96x96" }]
        }
    ],
    "share_target": {
        "action": "/share",
        "method": "POST",
        "enctype": "multipart/form-data",
        "params": {
            "title": "title",
            "text": "text",
            "url": "url"
        }
    }
}
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#1a73e8">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="apple-mobile-web-app-title" content="ТехноМагазин">
<link rel="apple-touch-icon" href="/icons/icon-192.png">

Дополнительно: рекомендуем прочитать документацию Web App Manifest для глубокого понимания.

Почему Service Worker — основа PWA?

Service Worker — это прокси между браузером и сетью. Он перехватывает запросы и решает, отдавать ли кэш, слать запрос или показывать офлайн-страницу. Без него PWA не существует. Мы реализуем стратегию «Cache First для статики, Network First для HTML, Stale While Revalidate для медиа». Пример базового Service Worker:

// sw.js — базовая стратегия для PWA
const CACHE_VERSION = 'v3';
const APP_SHELL = [
    '/',
    '/manifest.json',
    '/offline.html',
    '/css/app.css',
    '/js/app.js',
    '/fonts/inter-regular.woff2',
    '/icons/icon-192.png',
];

// Установка: кешируем App Shell
self.addEventListener('install', event => {
    event.waitUntil(
        caches.open(`shell-${CACHE_VERSION}`)
            .then(cache => cache.addAll(APP_SHELL))
            .then(() => self.skipWaiting())
    );
});

// Активация: удаляем старые кеши
self.addEventListener('activate', event => {
    event.waitUntil(
        caches.keys()
            .then(keys => Promise.all(
                keys.filter(k => !k.endsWith(CACHE_VERSION))
                    .map(k => caches.delete(k))
            ))
            .then(() => self.clients.claim())
    );
});

// Fetch: разные стратегии для разных ресурсов
self.addEventListener('fetch', event => {
    const { request } = event;
    const url = new URL(request.url);

    // App Shell — cache first
    if (APP_SHELL.includes(url.pathname)) {
        event.respondWith(
            caches.match(request).then(r => r || fetch(request))
        );
        return;
    }

    // HTML-страницы — network first, fallback offline
    if (request.headers.get('Accept')?.includes('text/html')) {
        event.respondWith(
            fetch(request)
                .then(response => {
                    const clone = response.clone();
                    caches.open(`pages-${CACHE_VERSION}`)
                        .then(cache => cache.put(request, clone));
                    return response;
                })
                .catch(() => caches.match(request)
                    .then(cached => cached || caches.match('/offline.html'))
                )
        );
        return;
    }

    // Изображения — stale while revalidate
    if (request.destination === 'image') {
        event.respondWith(
            caches.open(`images-${CACHE_VERSION}`).then(async cache => {
                const cached = await cache.match(request);
                const fetchPromise = fetch(request).then(response => {
                    cache.put(request, response.clone());
                    return response;
                });
                return cached ?? fetchPromise;
            })
        );
    }
});

Подробнее о Service Worker читайте в справочнике MDN.

Как добавить кнопку установки на сайт?

Чтобы пользователь мог установить PWA, нужно обработать событие beforeinstallprompt. Мы реализуем React-хук useInstallPrompt:

// useInstallPrompt.ts
export function useInstallPrompt() {
    const [installPrompt, setInstallPrompt] = useState<BeforeInstallPromptEvent | null>(null);
    const [isInstalled, setIsInstalled] = useState(false);

    useEffect(() => {
        const handler = (e: BeforeInstallPromptEvent) => {
            e.preventDefault();
            setInstallPrompt(e);
        };

        window.addEventListener('beforeinstallprompt', handler as EventListener);
        window.addEventListener('appinstalled', () => setIsInstalled(true));

        // Проверить — уже установлено?
        if (window.matchMedia('(display-mode: standalone)').matches) {
            setIsInstalled(true);
        }

        return () => window.removeEventListener('beforeinstallprompt', handler as EventListener);
    }, []);

    const install = async () => {
        if (!installPrompt) return;
        const result = await installPrompt.prompt();
        if (result.outcome === 'accepted') {
            setIsInstalled(true);
            setInstallPrompt(null);
        }
    };

    return { canInstall: !!installPrompt && !isInstalled, install, isInstalled };
}

// Использование в компоненте
function InstallBanner() {
    const { canInstall, install } = useInstallPrompt();
    if (!canInstall) return null;

    return (
        <div className="install-banner">
            <p>Установите приложение для быстрого доступа</p>
            <button onClick={install}>Установить</button>
        </div>
    );
}

Пример offline-страницы

<!-- /offline.html -->
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Нет соединения — ТехноМагазин</title>
    <style>
        body { font-family: system-ui; display: flex; align-items: center;
               justify-content: center; height: 100vh; margin: 0; }
        .offline { text-align: center; }
    </style>
</head>
<body>
    <div class="offline">
        <svg><!-- иконка wifi off --></svg>
        <h1>Нет соединения</h1>
        <p>Проверьте подключение к интернету и обновите страницу</p>
        <button onclick="location.reload()">Попробовать снова</button>
    </div>
</body>
</html>

Почему PWA не устанавливается: типичные ошибки

Даже при корректном манифесте и Service Worker установка может не сработать. Частая причина — отсутствие HTTPS или неправильные иконки. На iOS требуется явно указать apple-mobile-web-app-capable и добавить иконки нужных размеров. Ещё одна проблема: браузер отклоняет установку, если сайт не соответствует критериям качества (Lighthouse PWA audit). Мы проверяем все эти моменты: тестируем на Chrome, Safari, Firefox, Android и iOS. Если push-уведомления не работают, скорее всего, не настроен VAPID-ключ или сертификат. Все эти нюансы мы отрабатываем на этапе тестирования.

Что входит в работу

  • Web App Manifest — полная конфигурация с иконками, сплэшами, шорткатами.
  • Service Worker — регистрация, стратегии кэширования, обновление версий.
  • Offline-страница — адаптивная, с кнопкой перезагрузки.
  • Install Prompt — кнопка установки на десктоп и мобильные.
  • Push-уведомления — опционально, интеграция с Firebase или сторонним сервисом.
  • Аудит Lighthouse — гарантируем зелёные проверки PWA раздела.
  • Документация — описание архитектуры кэширования и инструкция по обновлению.

Сроки разработки

Этап Время
Манифест и мета-теги 0.5 дня
Service Worker + стратегии 1–1.5 дня
Offline-страница 0.5 дня
Install Prompt и тестирование 0.5 дня
Push-уведомления (опционально) +1–2 дня

Итоговый срок: от 2 до 4 дней без push, до 6 дней с ними. Стоимость рассчитывается индивидуально — пишите, оценим ваш проект.

Как мы работаем

  1. Аналитика — изучаем структуру сайта, определяем App Shell.
  2. Проектирование — выбираем стратегии кэширования под ваш контент.
  3. Реализация — пишем Service Worker, настраиваем манифест, интегрируем хуки.
  4. Тестирование — проверяем на Chrome, Safari, Firefox, Android и iOS.
  5. Деплой — загружаем на продакшен, мониторим через Lighthouse.

Наша команда имеет 5+ лет опыта в PWA. За это время реализовали проекты для интернет-магазинов, медиа и SaaS. Гарантируем поддержку актуальных стандартов и совместимость с последними версиями браузеров. Свяжитесь с нами, чтобы получить консультацию — расскажем, как PWA улучшит ваш бизнес. Закажите внедрение 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. Свяжитесь с нами для консультации — мы бесплатно оценим ваш проект и предложим оптимальную стратегию внедрения.

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