PWA: создайте мобильное приложение без App Store и Google Play
Для кого эта статья:
- Разработчики и программисты, интересующиеся веб-технологиями.
- Владельцы и управленцы бизнеса, заинтересованные в улучшении мобильного присутствия.
Студенты и новички в области веб-разработки, желающие изучить PWA.
Мобильные приложения — необходимость для бизнеса, но разработка под каждую платформу требует значительных ресурсов. Прогрессивные веб-приложения (PWA) решают эту проблему, позволяя создавать кроссплатформенные приложения без App Store и Google Play. PWA сочетают лучшие качества веб-сайтов и нативных приложений: работают офлайн, отправляют уведомления и используют аппаратные возможности устройств. Вы получаете полноценное приложение по цене веб-сайта — действительно прогрессивное решение для современного бизнеса. 🚀
Хотите создавать PWA самостоятельно? Курс Обучение веб-разработке от Skypro даст вам все необходимые навыки для разработки прогрессивных веб-приложений с нуля. Вы научитесь работать с Service Worker API, манифестами и современными фреймворками под руководством практикующих разработчиков. Всего за 9 месяцев вы сможете создавать PWA, которые превосходят большинство нативных аналогов!
PWA: фундамент прогрессивных веб-приложений
Прогрессивные веб-приложения (PWA) представляют собой веб-сайты, которые используют современные технологии для обеспечения пользовательского опыта, сравнимого с нативными приложениями. Концепция PWA была представлена Google в 2015 году и с тех пор трансформировала веб-разработку. 📱
PWA работают в любом браузере, но постепенно раскрывают более продвинутые функции на устройствах, которые их поддерживают — отсюда и слово "прогрессивные". Ключевая идея проста: предоставить единое приложение, которое адаптируется к возможностям устройства пользователя.
Принципиальное отличие PWA от обычных веб-сайтов заключается в трех фундаментальных технологиях:
- Service Worker — JavaScript-файл, который работает отдельно от основного потока браузера, перехватывает сетевые запросы и кэширует ресурсы для офлайн-работы.
- Web App Manifest — JSON-файл, который сообщает браузеру, как отображать и управлять приложением, включая иконки, тему и режим отображения.
- HTTPS — шифрованный протокол, обязательный для PWA, обеспечивающий безопасность данных пользователей.
PWA отлично зарекомендовали себя у крупных компаний. Twitter Lite, Pinterest, Starbucks и Uber улучшили вовлеченность пользователей, сократили размер приложения и увеличили конверсию после перехода на PWA.
| Компания | Результаты внедрения PWA |
|---|---|
| Twitter Lite | Увеличение количества страниц на сессию на 65%, снижение количества отказов на 20% |
| Рост конверсии на 60%, увеличение вовлеченности на 40% | |
| Starbucks | Размер PWA в 99.84% меньше, чем iOS-приложение, удвоение ежедневных активных пользователей |
| Uber | Работает даже на устройствах с 2G-соединением, начальная загрузка менее 3 секунд |
Александр Петров, технический директор Для нашего e-commerce проекта скорость загрузки страниц была критической проблемой — средняя конверсия падала на 12% при каждой дополнительной секунде загрузки. Мы решили перейти на PWA, хотя команда сомневалась в эффективности. Потратив 6 недель на разработку, мы запустили прогрессивную версию сайта. Результаты превзошли ожидания: время загрузки сократилось на 67%, конверсия выросла на 22%, а показатель отказов снизился на 18%. Самым впечатляющим оказался рост продаж через мобильные устройства — на 34%, причем многие покупки совершались даже при нестабильном интернете. PWA полностью изменило наше представление о мобильной коммерции.

Технические преимущества PWA над нативными решениями
Прогрессивные веб-приложения предлагают существенные технические преимущества в сравнении с традиционными нативными приложениями. При принятии решения о выборе технологии для вашего проекта, анализ этих преимуществ поможет оптимизировать ресурсы и удовлетворить требования пользователей. 🔍
Одно из главных преимуществ — универсальность кодовой базы. В отличие от нативных приложений, требующих отдельной разработки под iOS, Android и другие платформы, PWA используют единый код, что радикально снижает затраты на разработку и поддержку.
Процесс распространения PWA также значительно упрощен. Нативные приложения требуют прохождения модерации в App Store или Google Play, а PWA устанавливаются непосредственно с веб-сайта без каких-либо посредников. Это экономит время и ресурсы, особенно при выпуске обновлений.
Рассмотрим ключевые технические преимущества PWA в сравнении с нативными приложениями:
| Параметр | PWA | Нативные приложения |
|---|---|---|
| Размер приложения | ~1-3 МБ | ~30-100 МБ |
| Обновления | Автоматически при посещении сайта | Требуют ручной установки пользователем |
| Процесс установки | Моментальная установка через браузер | Загрузка из магазина приложений, требуется одобрение |
| Разработка | Единая кодовая база для всех платформ | Отдельные кодовые базы для iOS и Android |
| Доступ к API устройства | Ограниченный, но постоянно расширяющийся | Полный доступ ко всем возможностям устройства |
Что касается производительности, PWA часто превосходят нативные аналоги в скорости загрузки благодаря эффективному кэшированию. Service Worker обеспечивает мгновенную загрузку при повторных посещениях и работу даже в офлайн-режиме.
PWA также предлагают расширенную функциональность по сравнению с традиционными веб-сайтами:
- Push-уведомления для повторного вовлечения пользователей
- Фоновая синхронизация данных при восстановлении соединения
- Доступ к геолокации, камере, микрофону и другим API устройства
- Возможность работы в полноэкранном режиме без адресной строки браузера
- Добавление иконки на домашний экран устройства
Необходимо отметить, что PWA имеют и ограничения. Доступ к некоторым нативным функциям (особенно на iOS) остается ограниченным, включая Bluetooth, определенные датчики устройства и интеграцию с системными приложениями.
Мария Соколова, руководитель отдела разработки Мы столкнулись с дилеммой: клиент требовал приложение для Android и iOS с ограниченным бюджетом и сжатыми сроками. Два отдельных нативных приложения означали двойные затраты и риск не уложиться в дедлайн. Я предложила PWA как альтернативу, хотя команда сомневалась, что это удовлетворит заказчика. Мы подготовили презентацию, показав, что PWA сэкономит 60% бюджета и позволит запуститься на 8 недель раньше. Клиент согласился на эксперимент. Разработка заняла всего 10 недель вместо запланированных 18 для нативных приложений. Самым приятным сюрпризом стало то, что PWA работало быстрее, чем старое нативное приложение конкурентов. Теперь клиент называет PWA "лучшим бизнес-решением года" и рекомендует нас партнерам.
Ключевые компоненты для создания PWA с нуля
Создание эффективного PWA требует правильной архитектуры и интеграции нескольких ключевых компонентов. Рассмотрим основные элементы, без которых невозможно построить полноценное прогрессивное веб-приложение. 🏗️
Service Worker является сердцем любого PWA и выполняет критические функции перехвата сетевых запросов, кэширования и предоставления контента в офлайн-режиме. Это JavaScript-файл, который работает в фоновом режиме независимо от веб-страницы, даже когда браузер закрыт.
Базовая структура Service Worker включает три основных события:
- install — выполняется при установке Service Worker, идеально подходит для предварительного кэширования статических ресурсов
- activate — запускается после установки, используется для очистки ресурсов от предыдущих версий
- fetch — срабатывает при каждом сетевом запросе, позволяет реализовать различные стратегии кэширования
Вот пример простого Service Worker для кэширования статических ресурсов:
// Определяем имя кэша и ресурсы для предварительного кэширования
const CACHE_NAME = 'pwa-cache-v1';
const urlsToCache = [
'/',
'/styles/main.css',
'/scripts/app.js',
'/images/logo.png',
'/offline.html'
];
// Событие установки – кэширует ресурсы
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
// Событие fetch – обслуживает запросы из кэша
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
// Возвращаем кэшированный ответ, если он существует
if (response) {
return response;
}
// Иначе делаем сетевой запрос
return fetch(event.request)
.then(response => {
// Проверяем валидность ответа
if(!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// Клонируем ответ, так как он может быть использован только один раз
const responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(cache => {
cache.put(event.request, responseToCache);
});
return response;
})
.catch(() => {
// При отсутствии соединения возвращаем офлайн-страницу
if (event.request.mode === 'navigate') {
return caches.match('/offline.html');
}
});
})
);
});
Второй ключевой компонент — Web App Manifest, JSON-файл, описывающий метаданные приложения. Он определяет, как PWA должно отображаться на устройстве пользователя.
Пример базового manifest.json:
{
"name": "Мое PWA приложение",
"short_name": "PWA App",
"start_url": "/index.html",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#2196F3",
"orientation": "portrait",
"icons": [
{
"src": "/images/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/images/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
Для включения манифеста в HTML-документ используйте следующий тег:
<link rel="manifest" href="/manifest.json">
Помимо основных компонентов, эффективное PWA требует:
- Адаптивный дизайн — сайт должен корректно отображаться на любых устройствах
- HTTPS — обязательный компонент для PWA, обеспечивающий безопасность
- Стратегии кэширования — определяют, как приложение загружает и сохраняет ресурсы
- Метатеги для iOS — добавляют поддержку функций PWA на устройствах Apple
Каждая стратегия кэширования подходит для определенных типов контента:
| Стратегия | Описание | Применение |
|---|---|---|
| Cache First | Сначала проверяет кэш, обращается к сети только при отсутствии ресурса | Статические ресурсы (CSS, JS, изображения) |
| Network First | Сначала пытается получить свежую версию из сети, при ошибке использует кэш | Динамический контент (API-запросы) |
| Stale While Revalidate | Возвращает кэшированную версию, одновременно обновляя кэш из сети | Ресурсы, где важны и скорость, и актуальность |
| Network Only | Всегда использует сеть, никогда не кэширует | Часто изменяющиеся данные (например, аналитика) |
| Cache Only | Всегда использует кэш, никогда не обращается к сети | Критические ресурсы, предварительно кэшированные при установке |
Правильная комбинация этих компонентов обеспечит создание надежного PWA, которое предоставит пользователям отличный опыт независимо от качества соединения.
Пошаговое руководство по разработке вашего первого PWA
Разработка первого PWA может показаться сложной задачей, но при соблюдении четкой последовательности действий процесс становится структурированным и понятным. Давайте пройдем полный цикл создания простого, но функционального прогрессивного веб-приложения. 📝
Шаг 1: Создание базового веб-приложения
Начните с создания простого HTML-документа и базовой структуры проекта:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#2196F3">
<title>Мое первое PWA</title>
<link rel="stylesheet" href="css/style.css">
<!-- iOS поддержка -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="PWA App">
<link rel="apple-touch-icon" href="images/icons/icon-152x152.png">
<!-- Манифест -->
<link rel="manifest" href="manifest.json">
</head>
<body>
<header>
<h1>Мое первое PWA</h1>
</header>
<main>
<div class="content">
<p>Это прогрессивное веб-приложение работает даже офлайн!</p>
<button id="installButton" style="display: none;">Установить приложение</button>
</div>
</main>
<script src="js/app.js"></script>
</body>
</html>
Шаг 2: Создание Web App Manifest
Создайте файл manifest.json в корне вашего проекта:
{
"name": "Мое первое прогрессивное веб-приложение",
"short_name": "Первое PWA",
"start_url": "index.html",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#2196F3",
"orientation": "portrait-primary",
"icons": [
{
"src": "images/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "images/icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "images/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "images/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "images/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "images/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "images/icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "images/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
Шаг 3: Создание Service Worker
Создайте файл sw.js в корне проекта:
const CACHE_NAME = 'pwa-cache-v1';
const urlsToCache = [
'/',
'/index.html',
'/css/style.css',
'/js/app.js',
'/offline.html',
'/images/offline-image.svg'
];
// Установка Service Worker и кэширование ресурсов
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
// Активация Service Worker
self.addEventListener('activate', event => {
const cacheWhitelist = [CACHE_NAME];
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheWhitelist.indexOf(cacheName) === -1) {
return caches.delete(cacheName);
}
})
);
})
);
});
// Стратегия Cache First для статических ресурсов
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
// Если ресурс в кэше, возвращаем его
if (response) {
return response;
}
// Иначе запрашиваем из сети
return fetch(event.request)
.then(response => {
// Проверяем валидность ответа
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// Клонируем ответ, так как он может быть использован только один раз
let responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(cache => {
cache.put(event.request, responseToCache);
});
return response;
})
.catch(() => {
// При ошибке загружаем офлайн-страницу для навигационных запросов
if (event.request.mode === 'navigate') {
return caches.match('/offline.html');
}
// Для изображений можно возвращать заглушку
if (event.request.destination === 'image') {
return caches.match('/images/offline-image.svg');
}
});
})
);
});
Шаг 4: Регистрация Service Worker
Создайте файл app.js в папке js для регистрации Service Worker:
// Проверяем поддержку Service Worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('ServiceWorker зарегистрирован успешно:', registration.scope);
})
.catch(error => {
console.log('Ошибка регистрации ServiceWorker:', error);
});
});
}
// Добавление функциональности установки PWA
let deferredPrompt;
const installButton = document.getElementById('installButton');
window.addEventListener('beforeinstallprompt', (e) => {
// Предотвращаем появление стандартного баннера установки
e.preventDefault();
// Сохраняем событие, чтобы использовать его позже
deferredPrompt = e;
// Показываем кнопку установки
installButton.style.display = 'block';
});
installButton.addEventListener('click', (e) => {
// Скрываем кнопку установки
installButton.style.display = 'none';
// Показываем диалог установки
deferredPrompt.prompt();
// Ожидаем ответ пользователя
deferredPrompt.userChoice.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('Пользователь установил PWA');
} else {
console.log('Пользователь отклонил установку PWA');
}
deferredPrompt = null;
});
});
// Определяем, было ли приложение установлено
window.addEventListener('appinstalled', (evt) => {
console.log('Приложение установлено!');
});
Шаг 5: Создание офлайн-страницы
Создайте offline.html для отображения, когда пользователь не имеет соединения:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Офлайн режим</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<header>
<h1>Нет подключения к интернету</h1>
</header>
<main>
<div class="content">
<img src="images/offline-image.svg" alt="Офлайн режим" width="200">
<p>Проверьте подключение к интернету и попробуйте снова.</p>
<button onclick="window.location.reload()">Обновить страницу</button>
</div>
</main>
</body>
</html>
Шаг 6: Тестирование PWA
Для полноценного тестирования PWA необходимо:
- Запустить приложение на локальном HTTPS-сервере (или использовать инструменты вроде ngrok для туннелирования)
- Использовать Lighthouse в Chrome DevTools для проверки соответствия требованиям PWA
- Тестировать установку приложения на различных устройствах
- Проверять работу в режиме офлайн путем отключения интернета в браузере
Для проверки правильности реализации Service Worker используйте вкладку Application в DevTools:
- Откройте Chrome DevTools (F12)
- Перейдите на вкладку Application
- В левой панели выберите Service Workers
- Убедитесь, что ваш Service Worker активен
- Проверьте Cache Storage для подтверждения кэширования ресурсов
После выполнения всех шагов вы получите базовое, но полнофункциональное PWA, которое можно установить на устройства пользователей и которое будет работать даже при отсутствии интернета. 🚀
Оптимизация и тестирование PWA для разных устройств
После создания базового PWA наступает не менее важный этап — оптимизация и тестирование приложения для обеспечения высокой производительности на различных устройствах. Без должного внимания к этому этапу даже технически совершенное PWA может не обеспечить ожидаемого пользовательского опыта. 🧪
Производительность — ключевой фактор успеха PWA. Google рекомендует следовать модели RAIL (Response, Animation, Idle, Load), которая задает четкие метрики эффективности:
- Response: отклик на действия пользователя менее чем за 100 мс
- Animation: 60 кадров в секунду для плавных анимаций
- Idle: эффективное использование периодов бездействия для предварительной загрузки
- Load: первый осмысленный рендеринг менее чем за 1 секунду
Для оценки качества PWA используйте Lighthouse — встроенный в Chrome инструмент аудита. Он анализирует приложение по нескольким категориям, включая производительность, доступность, SEO и соответствие требованиям PWA.
Процесс оптимизации PWA включает следующие ключевые стратегии:
Минимизация размера критических ресурсов. Используйте инструменты сжатия JavaScript и CSS, такие как Terser и cssnano. Применяйте code-splitting для загрузки только необходимого кода.
Оптимизация изображений. Используйте современные форматы WebP и AVIF, реализуйте ленивую загрузку для изображений вне области видимости и предоставляйте различные размеры изображений через тег
<code>srcset</code>.Реализация стратегий предварительной загрузки. Используйте теги
<code>preload</code>,<code>prefetch</code>и<code>preconnect</code>для оптимизации загрузки критических ресурсов:
<link rel="preload" href="critical.css" as="style">
<link rel="preload" href="critical-font.woff2" as="font" crossorigin>
<link rel="prefetch" href="non-critical-page.html">
<link rel="preconnect" href="https://api.example.com">
При тестировании PWA необходимо проверять работу приложения в различных сценариях и на разных устройствах:
| Сценарий тестирования | Что проверять | Инструменты |
|---|---|---|
| Офлайн-режим | Доступность основных функций, корректное отображение офлайн-страниц | DevTools (Network – Offline), Flight Mode на устройствах |
| Медленное соединение | Время загрузки, отзывчивость интерфейса при плохом соединении | DevTools (Network – Slow 3G/2G), Chrome DevTools Throttling |
| Различные браузеры | Совместимость, согласованность внешнего вида и функциональности | BrowserStack, CrossBrowserTesting |
| Разные устройства | Адаптивность, масштабирование, взаимодействие с сенсорным экраном | Реальные устройства, Chrome DevTools Device Mode |
| Установка | Процесс установки, отображение на домашнем экране, запуск | Реальные устройства (Android, iOS, десктоп) |
| Push-уведомления | Регистрация, получение и отображение уведомлений | Chrome DevTools (Application – Background Services) |
Особое внимание уделите тестированию на iOS-устройствах, так как они имеют специфические ограничения для PWA:
- Web App Manifest поддерживается частично
- Отсутствует поддержка push-уведомлений
- Ограниченное хранилище (до 50 МБ)
- Данные могут быть очищены, если устройство нуждается в пространстве
Для компенсации этих ограничений используйте мета-теги Apple:
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="PWA App">
<link rel="apple-touch-icon" href="images/icons/apple-icon-152x152.png">
<link rel="apple-touch-startup-image" href="images/splash/launch-640x1136.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)">
Для углубленной оптимизации производительности PWA реализуйте:
- Запись в IndexedDB вместо localStorage для эффективного хранения данных без блокирования основного потока
- Web Workers для выполнения тяжелых вычислений в фоновом режиме
- Кэширование шрифтов и иконок для ускорения повторных загрузок
- Бюджет производительности — установите жесткие лимиты на размер JS-бандлов и других ресурсов
Регулярно проводите аудит производительности вашего PWA, особенно после значимых обновлений. Используйте данные реальных пользователей (RUM) для выявления проблем, которые могут не проявляться в тестовой среде.
Прогрессивные веб-приложения трансформируют будущее веб-разработки, предлагая идеальный баланс между доступностью веб-сайтов и функциональностью нативных приложений. Освоив технологии Service Worker, манифестов и эффективных стратегий кэширования, вы получаете мощный инструмент, способный доставить контент пользователям даже в самых сложных условиях связи. PWA — это не просто технический тренд, а фундаментальный сдвиг в сторону более отзывчивого, надежного и вовлекающего веба. Приступайте к разработке своего PWA сегодня, и ваши пользователи оценят разницу уже завтра.