Почему PWA — это не тренд, а архитектурный выбор
Progressive Web App — это веб-приложение, которое устанавливается на устройство пользователя, работает офлайн, получает push-уведомления и не требует App Store или Google Play. Для B2B-компаний это означает: один кодбейс, одна команда, один релизный цикл вместо двух мобильных платформ.
Современные PWA закрывают 90-95% задач, которые раньше требовали нативной разработки. Оставшиеся 5-10% — это специфичные функции вроде Bluetooth Low Energy, ARKit или фоновых геолокационных сервисов, которые постепенно также становятся доступными через Web API.
Архитектура PWA: что под капотом
Service Worker
Service Worker — это JavaScript-файл, который браузер запускает в фоновом режиме, отдельно от страницы. Он перехватывает сетевые запросы, управляет кэшем и обеспечивает офлайн-работу. Это ядро любого PWA.
Базовый пример регистрации Service Worker:
main.js:
- if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js').then(reg => console.log('SW registered:', reg.scope)).catch(err => console.error('SW registration failed:', err)); }
sw.js с стратегей Cache-First:
- const CACHE_NAME = 'app-v1'; const ASSETS = ['/', '/index.html', '/styles.css', '/app.js', '/offline.html'];
- self.addEventListener('install', e => { e.waitUntil(caches.open(CACHE_NAME).then(cache => cache.addAll(ASSETS))); });
- self.addEventListener('fetch', e => { e.respondWith(caches.match(e.request).then(response => response || fetch(e.request))); });
Эта схема кэширует ключевые ресурсы при установке и отдаёт их из кэша при каждом запросе. Если ресурса нет в кэше — запрос идёт в сеть. Для B2B-приложений с нестабильным соединением это критично.
Web App Manifest
Manifest — это JSON-файл, который описывает, как PWA выглядит на домашнем экране: иконки, название, тему, ориентацию, режим запуска. Без него браузер не предложит установку.
Пример manifest.json:
- { "name": "DAMIR Studio CRM", "short_name": "DAMIR CRM", "start_url": "/", "display": "standalone", "background_color": "#0a0a0a", "theme_color": "#00ff88", "icons": [{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }] } }
Параметр display: standalone убирает адресную строку браузера — приложение выглядит как нативное. Параметр purpose: any maskable обеспечивает корректное отображение иконки на Android.
HTTPS — обязательное условие
Service Workers работают только по HTTPS. Исключение — localhost для разработки. Если ваш сайт на HTTP, PWA не активируется. Это не рекомендация, это жёсткое ограничение безопасности.
Когда PWA выгоднее нативного приложения
Рассмотрим реальный B2B-кейс: внутренний CRM для менеджеров по продажам, которые работают в полях. Нативное приложение потребует:
- iOS-разработчика (Swift/Objective-C) — от 250 000 руб./мес
- Android-разработчика (Kotlin/Java) — от 250 000 руб./мес
- Согласование в App Store (1-7 дней на ревью) и Google Play (1-3 дня)
- Раздельные релизные циклы и багфиксы для каждой платформы
- Отдельный бэкенд-API или адаптация существующего
PWA на базе существующего веб-проекта потребует:
- Добавления Service Worker — 1-2 дня разработчика
- Создания manifest.json и иконок — 0.5 дня
- Настройки push-уведомлений через Web Push API — 2-3 дня
- Тестирования офлайн-режима и установки — 1-2 дня
Итог: функциональный PWA для B2B-сценария запускается за 5-8 дней силами одного фронтенд-разработчика вместо 3-6 месяцев команды из двух мобильных разработчиков.
Стратегии кэширования для B2B-приложений
Cache-First для статики
CSS, JS, шрифты и изображения кэшируются при первой загрузке. Все последующие обращения идут из кэша мгновенно. Обновление происходит при изменении версии Service Worker.
Network-First для данных
API-запросы сначала идут в сеть. Если сети нет — отдаётся кэшированный ответ. Для CRM это означает, что менеджер видит последние данные при наличии интернета и актуальный кэш при его отсутствии.
Пример Network-First:
- self.addEventListener('fetch', e => { if (e.request.url.includes('/api/')) { e.respondWith(fetch(e.request).catch(() => caches.match(e.request))); } });
Stale-While-Revalidate
Отдаёт кэшированный ответ немедленно, параллельно делает сетевой запрос и обновляет кэш. Баланс между скоростью и актуальностью — идеален для новостных лент и дашбордов.
Push-уведомления в PWA
Web Push API позволяет отправлять уведомления пользователю даже когда приложение закрыто. Для B2B это значит: напоминания о задачах, уведомления о новых лидах, алерты о статусах заказов — всё без установки нативного приложения.
Подписка на push-уведомления:
- async function subscribeToPush() { const reg = await navigator.serviceWorker.ready; const subscription = await reg.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY) }); await sendSubscriptionToServer(subscription); }
На сервере используется VAPID-ключи для аутентификации и библиотеки вроде web-push для Node.js. Отправка уведомления занимает одну строку: webpush.sendNotification(subscription, JSON.stringify({ title: 'Новый лид', body: 'Заявка от ООО Ромашка' })).
Ограничения PWA в 2026 году
Несмотря на зрелость технологии, ограничения остаются:
- iOS: фоновые процессы ограничены 30 секундами, push-уведомления работают только на iOS 16.4+
- Нет прямого доступа к контактам, календарю и файловой системе вне sandbox
- Bluetooth и NFC — частичная поддержка через Web Bluetooth и Web NFC
- App Store и Google Play недоступны как каналы дистрибуции
- Ограниченный доступ к нативным SDK для AR и VR
Для большинства B2B-сценариев — CRM, дашборды, формы, каталоги, бронирования — этих ограничений не существует. PWA полностью покрывает потребности.
Метрики производительности PWA
PWA не освобождает от ответственности за производительность. Ключевые метрики для отслеживания:
- Core Web Vitals: LCP (Largest Contentful Paint) < 2.5 с, FID < 100 мс, CLS < 0.1
- Time to Interactive — время до интерактивности интерфейса
- Cache hit rate — доля запросов, отдающихся из кэша Service Worker
- Install conversion rate — процент пользователей, установивших PWA
- Offline usage rate — доля сессий в офлайн-режиме
Измеряйте через Lighthouse, Chrome DevTools Application-вкладку и пользовательскую аналитику. Lighthouse Audit для PWA проверяет: installable, works offline, splash screen, themed — четыре критерия, без которых PWA не считается полноценным.
Практический чеклист запуска PWA
Пошаговый план для конвертации существующего веб-проекта в PWA:
- 1. Настройте HTTPS на продакшене — без него ничего не заработает
- 2. Создайте manifest.json с иконками 192px и 512px, display: standalone
- 3. Добавьте ссылку на manifest в HTML: link rel=manifest href=/manifest.json
- 4. Напишите Service Worker с Cache-First для статики и Network-First для API
- 5. Зарегистрируйте Service Worker при загрузке страницы
- 6. Создайте offline.html — fallback-страницу для отсутствующего кэша
- 7. Сгенерируйте VAPID-ключи и настройте push-уведомления
- 8. Прогоните Lighthouse Audit и добейтесь PWA-скоринга 90+
- 9. Протестируйте установку на iOS и Android, офлайн-режим и push
- 10. Добавьте кнопку Установить приложение в интерфейс через beforeinstallprompt event
Заключение
PWA — это архитектурное решение, а не компромисс. Для B2B-продуктов, где скорость доставки и единый кодбейс важнее доступа к специфичным API платформы, Progressive Web Apps сокращают время разработки в 3-5 раз, а стоимость владения — в 2-3 раза. Один разработчик, один репозиторий, мгновенные обновления без ревью сторов — это стандарт для современной разработки клиентских приложений.
