ФронтендМобильные приложенияJavaScriptHTML / CSS

PWA на JavaScript: офлайн-карточки, которые можно установить как приложение

Превращаем сайт с учебными карточками в PWA: manifest, service worker, Cache API, localStorage, офлайн-проверка и установка на устройство.

Кодик

Автор

6 мин чтения

PWA остаётся веб-приложением, но manifest делает его устанавливаемым, а service worker может вернуть интерфейс из кеша без сети. Соберём учебные карточки, сохраним их в localStorage, добавим manifest и cache-first service worker. Затем выключим сеть в DevTools и проверим приложение холодным перезапуском, а не открытой вкладкой.

Кнопка «Установить» и офлайн-режим являются разными возможностями. Manifest описывает приложение, service worker управляет запросами, а пользовательские карточки требуют собственного хранения. В этой статье вы соберёте устанавливаемый набор карточек, работающий после отключения сети. Финальный результат можно проверить без догадок: manifest проходит проверку, иконки 192 и 512 доступны, offline reload показывает интерфейс и сохранённые карточки.

1Manifest

Имя, иконки, start_url и display описывают установленное приложение.

2Service worker

install кеширует shell, fetch возвращает кеш или сеть.

3Data

localStorage хранит карточки отдельно от файлов интерфейса.

Из чего состоит устанавливаемая PWA

index.html подключает manifest и регистрирует sw.js. Во время install worker складывает app shell в Cache API. При fetch он ищет совпадение в кеше и иначе идёт в сеть. Карточки пользователя остаются в localStorage и не входят в cache. Для PWA держите этапы раздельно: ввод, проверка, основное действие и вывод. Такой маршрут позволяет остановиться в конкретной точке, увидеть фактические данные и исправить одну причину вместо случайной перестановки строк.

ЭтапДействиеПроверяемый результат
ПосещениеСтраница регистрирует service workerBrowser начинает install
Precacheinstall добавляет shell filesКеш version v1 создан
Запросfetch ищет Request в cacheOffline получает Response
УстановкаManifest задаёт имя и iconsПриложение появляется в launcher

Manifest отвечает за установку, service worker за сеть, а localStorage за пользовательские данные. У PWA каждый этап оставляет наблюдаемый след, поэтому следующий шаг начинается только после проверки предыдущего.

Три слоя PWA-карточек
От входных данных до видимого результата. Каждая технология хранит свой тип состояния

PWA требует HTTPS или localhost. Открытие index.html через file:// не проверяет service worker и installability. Используйте Vite, localhost или опубликованный HTTPS origin.

Пишем 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 специально ограничен одним пользовательским сценарием, чтобы назначение каждой строки оставалось видимым.

Открытая вкладка и настоящий offline
Что отличает устойчивый проект от случайного запуска. 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 или networkPOST не кешируется
VersionОтделяет старый shellActivate удаляет прежний cache

Cache-first отлично подходит неизменяемым shell-файлам, но может показывать устаревший HTML. Для API часто выбирают network-first или stale-while-revalidate. Не кешируйте приватный response под общим ключом. Навигационный fallback должен быть осознанным, иначе 404 превратится в index.html. Installability отличается между браузерами: manifest является основой, но место кнопки и критерии promotion меняются. На iOS установка идёт через Share menu и не использует beforeinstallprompt.

Проверяйте offline после полного закрытия вкладки. Открытая страница уже находится в памяти и может выглядеть рабочей без service worker. Включите Offline, перезагрузите и откройте приложение заново.

Проверяем installability и настоящий offline

Проверьте manifest и icons в DevTools. Установите service worker, дождитесь activated и включите Offline. Сделайте hard reload. Затем измените CSS без смены CACHE и увидьте старую версию. Поменяйте v1 на v2 и повторите. Добавьте форму карточки с вопросом и ответом, сохраняйте массив в localStorage и восстанавливайте на старте. Удалите приложение и site data, затем пройдите установку с чистого состояния.

Проверка своими руками
  1. Проверьте manifest и две иконки.
  2. Дождитесь activated worker.
  3. Перезагрузите в Offline.
  4. Смените версию cache.
  5. Сохраните карточку в localStorage.
  6. Проверьте чистую установку повторно.
Готово, если выполняются все пункты
  • 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.

ШагЧто разобратьМини-проверка
1Manifest JSONОписать icons и start_url
2PromisesДождаться register
3Cache APIДобавить app shell
4Fetch eventВернуть cached Response
5Local storageВосстановить карточки

Сначала добейтесь offline shell, затем добавляйте пользовательские данные и сложные стратегии. Финальная проверка для PWA: закрыть статью, объяснить путь данных и добавить одну функцию без копирования готового блока.

Тестируют через file://

Service worker требует HTTPS или localhost.

Иконки только SVG

Для совместимой установки подготовьте требуемые PNG 192 и 512.

Имя кеша не меняется

Версионируйте cache при изменении shell.

Считают открытую вкладку offline-тестом

Перезагрузите страницу при отключённой сети.

Сверяйтесь с первичной документацией. Команды и ограничения примера проверены по официальному курсу web.dev Learn PWA. Если версия инструмента изменилась, официальный источник важнее старого скриншота.

Что получится в итоге

Готовый результат проекта: PWA на JavaScript: офлайн-карточки, которые можно установить как приложение
Карточки устанавливаются как приложение, app shell открывается без сети, а пользовательские данные сохраняются отдельно.

Короткие ответы
Что делает PWA устанавливаемой?

Web app manifest описывает имя, иконки, start_url и режим отображения для установки.

Обязателен ли service worker для установки PWA?

Критерии зависят от браузера, но service worker обычно нужен для полезного offline-режима, а manifest нужен для PWA.

Почему нужно менять имя cache?

Новая версия имени позволяет установить обновлённый shell и удалить старые файлы при activate.

Как понять, что учебный проект PWA действительно работает?

Проверьте основной сценарий PWA, неверный ввод, повторный запуск и один граничный случай. Затем объясните путь данных своими словами.

Можно ли начать с готового кода PWA из статьи?

Да. Сначала добейтесь результата PWA, затем измените одно правило и восстановите ключевой файл без копирования.

Проверьте три сценария: install, offline и update

JavaScript и сеть закрепите в курсе JavaScript, структуру страницы в HTML и CSS.

Возьмите данные из todo-листа, сетевой экран из приложения погоды и сравните мобильную упаковку с мобильным приложением с ИИ.