Офлайн-режим и офлайн-страница
Урок показывает, как собрать офлайн-режим: кеш оболочки и запасную офлайн-страницу.
Офлайн-режим — способность приложения открываться и показывать осмысленный контент, когда сети нет, благодаря заранее закешированным ресурсам.
Два уровня офлайна
Офлайн в PWA обычно строят в два слоя:
- Кеш оболочки и ассетов. При установке Service Worker кешируем всё, что нужно для отрисовки интерфейса: HTML-каркас, CSS, JS, иконки. Тогда офлайн приложение хотя бы откроется.
- Запасная офлайн-страница. Для запросов, которые нельзя отдать из кеша (например, страница, которую пользователь ещё не посещал), показываем дружелюбную страницу «Вы офлайн» вместо браузерной ошибки.
Кешируем оболочку на install
const CACHE = 'shell-v1';
const ASSETS = ['/', '/styles.css', '/app.js', '/offline.html', '/icons/icon-192.png'];
self.addEventListener('install', function (event) {
event.waitUntil(
caches.open(CACHE).then(function (cache) { return cache.addAll(ASSETS); })
);
});Запасная страница на fetch
В обработчике fetch для навигационных запросов (переходов по страницам) применяем network-first, а если сеть недоступна и в кеше ничего нет — отдаём /offline.html:
self.addEventListener('fetch', function (event) {
if (event.request.mode === 'navigate') {
event.respondWith(
fetch(event.request).catch(function () {
return caches.match(event.request)
.then(function (c) { return c || caches.match('/offline.html'); });
})
);
}
});Простая офлайн-страница
<!DOCTYPE html>
<html lang="ru">
<head><meta charset="utf-8"><title>Нет сети</title></head>
<body>
<h1>Вы офлайн</h1>
<p>Проверьте подключение к интернету и попробуйте снова.</p>
</body>
</html>Эта страница тоже должна быть в кеше (мы добавили её в ASSETS), иначе офлайн её неоткуда взять.
Как работает под капотом проверка онлайна
Браузер сообщает о состоянии сети через navigator.onLine и события online / offline. Но полагаться только на них рискованно: navigator.onLine === true означает лишь «есть сетевой интерфейс», а не «сервер доступен». Поэтому надёжнее реальная попытка fetch с catch: если запрос упал — считаем, что офлайн, и отдаём запасной ответ. Именно так устроен пример выше.
Частые ошибки
- Забыть закешировать саму офлайн-страницу. Тогда в офлайне Service Worker не сможет её отдать.
- Кешировать только HTML без CSS/JS. Страница откроется «голой» — без стилей и скриптов.
- Полагаться на navigator.onLine. Он не гарантирует доступность сервера; лучше ловить ошибку fetch.
- Не обрабатывать навигационные запросы отдельно. Без этого при переходе на новую страницу офлайн покажет браузерную ошибку.
Итоги
- Офлайн = кеш оболочки/ассетов + запасная офлайн-страница.
- Оболочку кешируем на
install, офлайн-страницу обязательно включаем в кеш. - В
fetchдля навигаций: сеть → кеш → офлайн-страница. - Надёжнее ловить ошибку
fetch, чем доверятьnavigator.onLine.