Progressive Web App: Service Worker, офлайн, Web Push, Add to Home Screen
PWA — це не окремена технологія, це набір браузерних API, які разом роблять веб-застосунок ближче до нативного. Можна реалізувати всі три компоненти (Service Worker, Web App Manifest, HTTPS), але отримати погане PWA. Можна зробити тільки офлайн-кешування та Web Push — і це вже дасть відчутну цінність для користувачів.
Service Worker: як це реально працює
Service Worker — це JavaScript-прокси між браузером та мережею. Працює в окремому потоці, немає доступу до DOM, живе незалежно від сторінки. Основна задача — перехоплювати сітьові запити та вирішувати, звідки їх віддавати: з кешу, з мережі, або комбінація.
Стратегії кешування для різних ресурсів:
Cache First — спочатку кеш, потім мережа. Для статичних ассетів з content hash у імені (скрипти, стилі, шрифти): файл з хешем не змінюється ніколи, можна кешувати вічно.
Network First — спочатку мережа, при помилці — кеш. Для API-запитів, які повинні повертати актуальні дані, але при офлайні краще показати застарілі ніж нічого.
Stale While Revalidate — віддаємо з кешу негайно, одночасно оновлюємо кеш з мережі. Для контенту, де невелика затримка актуалізації допустима: сторінки статей, каталог товарів.
Workbox від Google бере на себе рутинну логіку: версіонування кешу, очистка старих записів, стратегії. Без Workbox написати коректний Service Worker з правильною інвалідацією кешу — 300+ рядків коду з нетривіальними edge cases.
Vite + vite-plugin-pwa генерує Service Worker автоматично з конфіга, включаючи precaching всіх статичних ассетів після збірки.
Офлайн-режим: який він насправді
«Працює офлайн» для різних продуктів означає різне.
Офлайн-читання: новинні сайти, документація, блоги. Service Worker кешує сторінки при першому відвідуванні. Стратегія Stale While Revalidate + Background Sync для синхронізації коли з'єднання відновлюється.
Офлайн-редагування: завдання, нотатки, форми. IndexedDB зберігає невбудовані дані локально. Background Sync API ставить операцію в чергу — браузер сам синхронізує коли з'явиться з'єднання, навіть якщо вкладка закрита. Обмеження: Background Sync підтримується тільки в Chromium, у Safari — нема.
Офлайн-форма: користувач заповнив форму офлайн, натиснув відправити. Без PWA — помилка, дані втрачені. З Background Sync — форма ставиться в чергу, відправляється автоматично. Для медичних та страхових форм це критично важливо.
Проблема, про яку часто забувають: конфлікти при синхронізації. Користувач А редагував запис офлайн, користувач Б змінив її онлайн. При синхронізації — конфлікт. Потрібна стратегія розрішення: 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-ключі генеруються один раз. Підписка зберігається в базі даних — це ваш «токен» пристрою.
Обмеження за платформами в 2024:
- iOS 16.4+ підтримує Web Push, але тільки для встановлених PWA (доданих на домашній екран)
- Chrome, Firefox, Edge — повна підтримка у браузері без встановлення
- Safari macOS — підтримка з macOS Ventura
Частота відправки та релевантність сповіщень прямо впливають на відтік підписників. Користувачі відзивають дозвіл, якщо сповіщення нерелевантні. A/B тестування часу відправки та формулювань — стандартна практика.
Add to Home Screen та встановлення
Web App Manifest — JSON-файл з метаданими застосунку: name, short_name, icons (мінімум 192x192 і 512x512 PNG), start_url, display: standalone, theme_color, background_color.
display: standalone скриває браузерний UI — застосунок виглядає як нативний. display: minimal-ui залишає мінімальну навігацію браузера.
Браузер показує Install Prompt (beforeinstallprompt) при виконанні умов: HTTPS, валідний маніфест, Service Worker. Prompt можна відкласти та показати в потрібний момент (не одразу при завантаженні):
let deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault();
deferredPrompt = e;
});
// Пізніше, по дії користувача:
installButton.addEventListener('click', async () => {
deferredPrompt.prompt();
const { outcome } = await deferredPrompt.userChoice;
});
Після встановлення відслідковуйте через appinstalled подію та display-mode: standalone медіа-запит.
Продуктивність та PWA
App Shell архітектура: мінімальний HTML/CSS/JS, необхідний для рендера оболонки застосунку, кешується Service Worker та завантажується миттєво. Контент завантажується поверх. Різниця у сприйнятті швидкості — відчутна навіть при повільному з'єднанні.
Precaching критичних ресурсів при встановленні Service Worker: при першому відвідуванні кешуємо все необхідне для роботи офлайн. Розмір precache бандла впливає на час першого встановлення — не кладіть туди все підряд.
Процес роботи
Аудит поточного застосунку (Lighthouse PWA score), визначення цінних офлайн-сценаріїв, налаштування Service Worker через Workbox, реалізація Web Push якщо потрібно, тестування на реальних пристроях. Lighthouse PWA розділ та Chrome DevTools Application tab — основні інструменти налагодження.
Строки
Базова PWA (маніфест + Service Worker + офлайн-кеш статики): 1–2 тижні поверх готового застосунку. Web Push інтеграція: 1–2 тижні. Офлайн-редагування з IndexedDB + Background Sync: 3–6 тижнів залежно від складності даних.







