PWA: офлайн-режим и установка

Прогрессивное веб-приложение — это обычный сайт плюс манифест, Service Worker и работа без сети. Никакого нативного кода не требуется.

Web App Manifest Service Worker Офлайн

Живая проверка

В сети

Service Worker

Проверка…

Установка приложения

Проверка возможности установки…

Журнал событий…
Как проверить офлайн: откройте DevTools → вкладка Network → поставьте галочку Offline и обновите страницу. Она откроется из кеша.
Service Worker работает только по HTTPS или на localhost. На обычном http-хостинге регистрация не пройдёт — это требование безопасности браузеров.

1. Манифест

Файл manifest.webmanifest описывает приложение: имя, иконки, цвета, режим отображения и стартовый адрес.

index.html
<link rel="manifest" href="manifest.webmanifest">
<meta name="theme-color" content="#2563eb">
manifest.webmanifest
{
  "name": "Мобильные и веб-технологии, сервисы",
  "short_name": "Web&Mobile",
  "start_url": "./index.html",
  "scope": "./",
  "display": "standalone",
  "background_color": "#f5f7fb",
  "theme_color": "#2563eb",
  "icons": [
    { "src": "./icon.svg", "sizes": "any", "type": "image/svg+xml", "purpose": "any maskable" }
  ]
}

2. Регистрация Service Worker

js
if ('serviceWorker' in navigator) {
  window.addEventListener('load', async () => {
    try {
      const registration = await navigator.serviceWorker.register('/sw.js');
      console.log('SW зарегистрирован, область:', registration.scope);
    } catch (error) {
      console.error('Ошибка регистрации SW:', error);
    }
  });
}

Стратегии кеширования

СтратегияЛогикаДля чего
Cache FirstСначала кеш, сеть — при промахеСтатика: CSS, JS, шрифты, иконки
Network FirstСначала сеть, кеш — при сбоеHTML-страницы, часто обновляемые данные
Stale While RevalidateОтдаём кеш и параллельно обновляемКонтент, где важна скорость

3. Установка на устройство

js
let deferredPrompt = null;

window.addEventListener('beforeinstallprompt', (event) => {
  event.preventDefault();          // откладываем системный баннер
  deferredPrompt = event;
  installButton.disabled = false;  // показываем свою кнопку
});

installButton.addEventListener('click', async () => {
  if (!deferredPrompt) return;
  deferredPrompt.prompt();
  const { outcome } = await deferredPrompt.userChoice;
  console.log('Выбор пользователя:', outcome);   // 'accepted' | 'dismissed'
  deferredPrompt = null;
  installButton.disabled = true;
});
Chrome требует, чтобы у приложения были манифест, иконка не менее 192 px, Service Worker с обработчиком fetch и подключение по HTTPS.

Задание

  1. Добавьте в sw.js стратегию Network First для HTML-страниц и Cache First для картинок.
  2. Сделайте свою страницу-заглушку для офлайна и подключите её в обработчике fetch.
  3. Добавьте в интерфейс счётчик посещений, который работает без сети (подсказка: localStorage).
  4. Соберите отчёт: какие из ваших страниц уже проходят критерии устанавливаемого PWA, а какие нет.