PWA остаётся веб-приложением, но manifest делает его устанавливаемым, а service worker может вернуть интерфейс из кеша без сети. Соберём учебные карточки, сохраним их в localStorage, добавим manifest и cache-first service worker. Затем выключим сеть в DevTools и проверим приложение холодным перезапуском, а не открытой вкладкой.
Кнопка «Установить» и офлайн-режим являются разными возможностями. Manifest описывает приложение, service worker управляет запросами, а пользовательские карточки требуют собственного хранения. В этой статье вы соберёте устанавливаемый набор карточек, работающий после отключения сети. Финальный результат можно проверить без догадок: manifest проходит проверку, иконки 192 и 512 доступны, offline reload показывает интерфейс и сохранённые карточки.
Имя, иконки, start_url и display описывают установленное приложение.
install кеширует shell, fetch возвращает кеш или сеть.
localStorage хранит карточки отдельно от файлов интерфейса.
Из чего состоит устанавливаемая PWA
index.html подключает manifest и регистрирует sw.js. Во время install worker складывает app shell в Cache API. При fetch он ищет совпадение в кеше и иначе идёт в сеть. Карточки пользователя остаются в localStorage и не входят в cache. Для PWA держите этапы раздельно: ввод, проверка, основное действие и вывод. Такой маршрут позволяет остановиться в конкретной точке, увидеть фактические данные и исправить одну причину вместо случайной перестановки строк.
| Этап | Действие | Проверяемый результат |
|---|---|---|
| Посещение | Страница регистрирует service worker | Browser начинает install |
| Precache | install добавляет shell files | Кеш version v1 создан |
| Запрос | fetch ищет Request в cache | Offline получает Response |
| Установка | Manifest задаёт имя и icons | Приложение появляется в launcher |
Manifest отвечает за установку, service worker за сеть, а localStorage за пользовательские данные. У PWA каждый этап оставляет наблюдаемый след, поэтому следующий шаг начинается только после проверки предыдущего.

От входных данных до видимого результата. Каждая технология хранит свой тип состояния
Пишем manifest и service worker
Создайте vanilla Vite-проект или простой статический сайт. Подготовьте реальные PNG-иконки 192x192 и 512x512. Добавьте link rel="manifest" и регистрацию sw.js. Service worker должен лежать в корне, если он должен контролировать весь сайт. Запускайте через localhost, затем откройте Application в DevTools.
// main.js
if ("serviceWorker" in navigator) {
window.addEventListener("load", async () => {
try {
await navigator.serviceWorker.register("/sw.js");
console.log("service worker registered");
} catch (error) {
console.error("service worker failed", error);
}
});
}
// sw.js
const CACHE = "study-cards-v1";
const APP_SHELL = ["/", "/index.html", "/src/main.js", "/src/style.css"];
self.addEventListener("install", (event) => {
event.waitUntil(caches.open(CACHE).then((cache) => cache.addAll(APP_SHELL)));
});
self.addEventListener("activate", (event) => {
event.waitUntil(
caches.keys().then((keys) =>
Promise.all(keys.filter((key) => key !== CACHE).map((key) => caches.delete(key)))
)
);
});
self.addEventListener("fetch", (event) => {
if (event.request.method !== "GET") return;
event.respondWith(
caches.match(event.request).then((cached) => cached || fetch(event.request))
);
});- Регистрация проходит только на поддерживаемом secure origin.
- Install завершается после успешного cache.addAll.
- GET app-shell читается из Cache API без сети.
- Activate удаляет кеши с другим именем.
Название кеша является версией. При изменении shell увеличьте v1 до v2, иначе старые файлы продолжат побеждать сеть. Пример PWA специально ограничен одним пользовательским сценарием, чтобы назначение каждой строки оставалось видимым.

Что отличает устойчивый проект от случайного запуска. Reload без сети является обязательным тестом
Как cache-first работает без сети
Service worker работает в отдельном контексте без DOM. После регистрации браузер загружает скрипт, выполняет install и затем activate. Worker контролирует страницу не всегда мгновенно: первая открытая вкладка может потребовать reload. fetch событие перехватывает запросы в scope. Cache API хранит пары Request/Response, но не понимает бизнес-данные. localStorage доступен странице, но не service worker, поэтому крупные структурированные данные лучше переносить в IndexedDB.
| Часть | За что отвечает | Что проверить |
|---|---|---|
| Manifest | Описывает установку | Есть name, icons, start_url, display |
| Registration | Подключает worker | Ошибка видна в console |
| Install | Заполняет cache | Все shell files существуют |
| Fetch | Выбирает cache или network | POST не кешируется |
| Version | Отделяет старый shell | Activate удаляет прежний cache |
Cache-first отлично подходит неизменяемым shell-файлам, но может показывать устаревший HTML. Для API часто выбирают network-first или stale-while-revalidate. Не кешируйте приватный response под общим ключом. Навигационный fallback должен быть осознанным, иначе 404 превратится в index.html. Installability отличается между браузерами: manifest является основой, но место кнопки и критерии promotion меняются. На iOS установка идёт через Share menu и не использует beforeinstallprompt.
Проверяем installability и настоящий offline
Проверьте manifest и icons в DevTools. Установите service worker, дождитесь activated и включите Offline. Сделайте hard reload. Затем измените CSS без смены CACHE и увидьте старую версию. Поменяйте v1 на v2 и повторите. Добавьте форму карточки с вопросом и ответом, сохраняйте массив в localStorage и восстанавливайте на старте. Удалите приложение и site data, затем пройдите установку с чистого состояния.
- Проверьте manifest и две иконки.
- Дождитесь activated worker.
- Перезагрузите в Offline.
- Смените версию cache.
- Сохраните карточку в localStorage.
- Проверьте чистую установку повторно.
- Manifest валиден.
- Shell работает offline.
- Cache обновляется версией.
- Карточки переживают reload.
PWA готова только тогда, когда чистая установка, offline и обновление проверены как три разных сценария. После этой проверки измените одно правило PWA и заранее запишите ожидаемый результат. Так копирование превращается в понимание.

Четыре проверки перед следующим шагом. Обновление проверяется отдельно
Как обновлять PWA и не оставлять старый кеш
Дальше перенесите карточки в IndexedDB, добавьте импорт и экспорт, а стратегию кеша разделите по типу ресурса. Для production используйте библиотеку вроде Workbox только после понимания базовых событий. Показывайте пользователю, что доступна новая версия, а не перезагружайте приложение посреди работы. Проверяйте install на Android, desktop и iOS отдельно. Push notifications требуют разрешения и серверной части, они не являются обязательным признаком PWA.
Как изучить тему в Кодике
Повторите fetch, Promise, события и localStorage JavaScript, затем изучите отдельный worker-контекст. В Кодике сначала восстановите чистую логику без фреймворка, затем верните библиотеку и интерфейс PWA.
| Шаг | Что разобрать | Мини-проверка |
|---|---|---|
| 1 | Manifest JSON | Описать icons и start_url |
| 2 | Promises | Дождаться register |
| 3 | Cache API | Добавить app shell |
| 4 | Fetch event | Вернуть cached Response |
| 5 | Local storage | Восстановить карточки |
Сначала добейтесь offline shell, затем добавляйте пользовательские данные и сложные стратегии. Финальная проверка для PWA: закрыть статью, объяснить путь данных и добавить одну функцию без копирования готового блока.
Service worker требует HTTPS или localhost.
Для совместимой установки подготовьте требуемые PNG 192 и 512.
Версионируйте cache при изменении shell.
Перезагрузите страницу при отключённой сети.
Что получится в итоге

Карточки устанавливаются как приложение, app shell открывается без сети, а пользовательские данные сохраняются отдельно.
Что делает PWA устанавливаемой?
Web app manifest описывает имя, иконки, start_url и режим отображения для установки.
Обязателен ли service worker для установки PWA?
Критерии зависят от браузера, но service worker обычно нужен для полезного offline-режима, а manifest нужен для PWA.
Почему нужно менять имя cache?
Новая версия имени позволяет установить обновлённый shell и удалить старые файлы при activate.
Как понять, что учебный проект PWA действительно работает?
Проверьте основной сценарий PWA, неверный ввод, повторный запуск и один граничный случай. Затем объясните путь данных своими словами.
Можно ли начать с готового кода PWA из статьи?
Да. Сначала добейтесь результата PWA, затем измените одно правило и восстановите ключевой файл без копирования.
JavaScript и сеть закрепите в курсе JavaScript, структуру страницы в HTML и CSS.
Возьмите данные из todo-листа, сетевой экран из приложения погоды и сравните мобильную упаковку с мобильным приложением с ИИ.