Большинство приложений на вашем телефоне по своей сути мало чем отличаются от обычного веб-сайта — просто у них есть отдельный значок на экране и они частично работают без интернета. Progressive Web App (PWA) — это технология, которая стирает именно эту границу: оставаясь полноценным веб-сайтом, она ведёт себя как мобильное приложение. Пользователь устанавливает её на главный экран, получает push-уведомления и может просматривать страницы офлайн. Для веб-разработчика это самый дешёвый и быстрый способ дать аудитории нативный опыт без отдельной мобильной команды.
Что такое PWA и почему это важно
PWA — это сайт, построенный на современных веб-стандартах (HTML, CSS, JavaScript), но дополненный возможностями, характерными для нативных приложений. Вся магия держится на трёх китах: файл манифеста описывает, как приложение устанавливается и выглядит, service worker перехватывает сетевые запросы и обеспечивает офлайн-работу и кеширование, а HTTPS гарантирует безопасность всей системы. Когда эта тройка работает слаженно, пользователь может установить приложение, вообще не заходя в App Store или Play Market.
С точки зрения бизнеса PWA крайне привлекателен, потому что одной кодовой базой вы получаете и браузерный, и «приложенческий» опыт. Вам не нужна отдельная команда под iOS и Android, отдельная регистрация в магазинах или ожидание модерации при каждом обновлении. Стоит обновить сайт — и при следующем открытии пользователь автоматически получает свежую версию. Это экономит время и деньги, особенно для малых и средних проектов, где ресурсы ограничены.
manifest.json — паспорт приложения
Первый шаг к тому, чтобы ваше веб-приложение можно было установить, — создать файл манифеста. Этот JSON-файл сообщает браузеру имя приложения, иконки, цвета и режим отображения. Вы подключаете его в head HTML-страницы, и браузер на основе этих данных предлагает «Добавить на главный экран».
{
"name": "Мой Магазин",
"short_name": "Магазин",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#0d6efd",
"icons": [
{
"src": "/icons/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icons/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
Здесь ключевое поле — display: значение standalone заставляет приложение открываться без адресной строки браузера, то есть на весь экран, как настоящая программа. Для иконок рекомендуется задавать как минимум размеры 192 и 512 пикселей, поскольку разные устройства используют разные размеры. Поле theme_color при этом окрашивает строку статуса в фирменный цвет, усиливая ощущение полноценного приложения.
Service worker — сердце офлайн-работы
Service worker — это JavaScript-скрипт, который работает в фоне, отдельно от страницы. Он стоит между браузером и сетью и может перехватить любой запрос, отдав ответ из кеша или направив его в сеть. Именно этот механизм позволяет сайту продолжать работать даже при потере соединения. Сначала вы регистрируете service worker, а затем внутри него описываете стратегию кеширования.
// app.js — регистрация service worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then(reg => console.log('SW registered', reg.scope))
.catch(err => console.log('SW error', err));
});
}
После регистрации в файле sw.js мы сохраняем важные страницы в кеш и перехватываем запросы. В примере ниже на этапе install кешируются основные файлы, а на этапе fetch ответ берётся сначала из кеша, и только если его там нет — из сети.
// sw.js
const CACHE = 'app-v1';
const ASSETS = ['/', '/index.html', '/styles.css', '/app.js'];
self.addEventListener('install', e => {
e.waitUntil(
caches.open(CACHE).then(c => c.addAll(ASSETS))
);
});
self.addEventListener('fetch', e => {
e.respondWith(
caches.match(e.request).then(res => res || fetch(e.request))
);
});
Такая стратегия называется cache-first: если файл есть в кеше, он отдаётся мгновенно, что делает открытие страницы очень быстрым. Там, где нужны более свежие данные, применяют стратегии network-first или stale-while-revalidate. Выбор стратегии под содержание сайта — задача разработчика, и от него во многом зависит ощущение скорости.
Push-уведомления и установка
PWA умеет общаться с пользователем как нативное приложение: через push-уведомления можно сообщать о новом сообщении, скидке или статусе заказа. Для этого вы запрашиваете у пользователя разрешение и показываете уведомление через service worker. Процесс установки при этом предельно прост — браузер при выполнении нужных условий сам предлагает кнопку «Добавить на экран», либо вы можете управлять этим вручную.
// Управление предложением установки
let deferredPrompt;
window.addEventListener('beforeinstallprompt', e => {
e.preventDefault();
deferredPrompt = e;
showInstallButton();
});
installBtn.addEventListener('click', async () => {
deferredPrompt.prompt();
const choice = await deferredPrompt.userChoice;
console.log('Результат:', choice.outcome);
});
Ограничения и когда выбирать нативное приложение
PWA не является идеальным решением для всего. На платформе iOS Apple ограничивает возможности PWA: push-уведомления долго не поддерживались и до сих пор имеют ограничения, объём кеша лимитирован, а доступ к некоторым датчикам устройства неполный. Если ваш проект требует Bluetooth, продвинутых функций камеры, тяжёлой 3D-графики или глубокой интеграции с системой, нативное приложение по-прежнему остаётся более сильным выбором.
Тем не менее для большинства бизнес-проектов — интернет-магазинов, новостных сайтов, сервисных платформ и внутренних инструментов — PWA даёт идеальный баланс. Он дёшев, быстро запускается, одной кодовой базой охватывает все платформы и не зависит от модерации в магазинах. Начиная проект, сначала рассмотрите вариант сборки в виде PWA и переходите на нативное приложение только при реальной необходимости — в большинстве случаев это самая разумная стратегия.