Разработка Progressive Web App (PWA) для мобильных устройств
Клиент хочет мобильное присутствие без публикации в App Store и Google Play. Или у него уже есть веб-сайт на React/Vue/Angular, и нужно добавить офлайн-режим, push-уведомления и иконку на домашнем экране — без переписывания всего с нуля. PWA закрывает этот запрос, но «просто добавить manifest.json» — это не PWA.
Реальная PWA — это Service Worker с правильной стратегией кэширования, Web App Manifest с корректными параметрами для каждой платформы, и HTTPS без исключений. Пропустить любой из этих трёх компонентов — получить приложение, которое не устанавливается или работает некорректно в офлайне.
Где обычно ломается
Service Worker и стратегии кэширования. Самая частая ошибка — кэшировать всё подряд с CacheFirst без инвалидации. Пользователь открывает обновлённое приложение, а видит старую версию, потому что sw.js отдаёт ресурсы из устаревшего кэша. Workbox решает это через StaleWhileRevalidate для статики и NetworkFirst для API-запросов, но нужно чётко разделить, что кэшировать агрессивно (шрифты, иконки, JS-бандлы с хэшами), а что всегда запрашивать свежее (данные пользователя, инвентарь, контент).
Отдельная история — фоновая синхронизация через Background Sync API. Пользователь отправил форму в офлайне, Service Worker перехватил запрос и положил в SyncManager. Когда связь восстановилась — запрос ушёл. Выглядит просто, но registration.sync.register('sync-orders') работает только в Chrome/Android. На iOS Safari Background Sync до сих пор не поддерживается — это нужно учитывать при проектировании офлайн-сценариев.
iOS Safari и его ограничения. Apple планомерно ограничивает PWA: до iOS 16.4 push-уведомления в PWA не работали вообще. Сейчас работают, но только если приложение добавлено на домашний экран через Safari — не из Chrome, не из Firefox. Квота хранилища IndexedDB на iOS — 50 МБ по умолчанию, против гигабайтов на Android. Кэшируемые ресурсы нужно считать заранее.
Как строим PWA
Основа — Workbox 7.x, встроенный в Vite через vite-plugin-pwa. Конфигурация generateSW покрывает 80% кейсов: плагин автоматически создаёт precache-манифест из бандла и регистрирует Service Worker. Для сложных сценариев — injectManifest режим с ручным sw.js.
Манифест для корректной установки на обеих платформах требует минимум: name, short_name, start_url с параметром ?source=pwa, display: standalone, theme_color, background_color, и набор иконок — 192×192 и 512×512 в PNG, плюс maskable вариант для Android Adaptive Icons. Без maskable иконка на Android показывается с белым фоном в круге — выглядит непрофессионально.
Push-уведомления через Web Push Protocol: VAPID-ключи генерируются один раз, публичный ключ передаётся клиенту при подписке через PushManager.subscribe(). На сервере — web-push библиотека для Node.js или аналог. Subscription объект с endpoint, p256dh и auth сохраняется в базе — именно он нужен для отправки.
// Регистрация подписки
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(PUBLIC_VAPID_KEY)
});
Installability. Chrome показывает баннер «Добавить на главный экран» при выполнении критериев: HTTPS, валидный манифест, зарегистрированный SW с fetch-обработчиком. Lighthouse проверяет все условия. На iOS установка только вручную через Share → «На экран «Домой»» — никаких автоматических промптов.
Для измерения конверсии установок используем beforeinstallprompt event: перехватываем его, откладываем через event.preventDefault(), показываем собственный UI в нужный момент, затем вызываем prompt(). Это даёт контроль над тем, когда и кому предлагать установку.
Что входит в работу
Аудит существующего фронтенда — производительность (Core Web Vitals), HTTPS-конфигурация, текущий Service Worker если есть. Разработка SW со стратегиями кэширования под конкретные маршруты. Манифест, иконки всех размеров, splash screens для iOS. Push-уведомления если нужны. Тестирование офлайн-сценариев в Chrome DevTools (Application → Service Workers → Offline) и на реальных устройствах.
Итог проверяем через Lighthouse PWA audit — все пункты должны быть зелёными.
Сроки
Добавление PWA к готовому веб-приложению: 3–7 дней. Разработка PWA с нуля с офлайн-логикой и push-уведомлениями: 2–4 недели. Стоимость рассчитывается после анализа текущего стека и требований к офлайн-функциональности.







