Включите поддержку офлайн-режима в веб-приложениях с помощью Service Workers
Рабочие процессы и API кэширования позволяют сайту загружаться мгновенно и продолжать работать в офлайн-режиме. Написание кода рабочего процесса, его регистрация и выбор стратегий кэширования.
Источники: ☕ JavaScript Hack That Makes Any Website Work Offline
Представьте, что кто-то просматривает ваш сайт в поезде, при этом сигнал время от времени пропадает на несколько секунд. На большинстве веб-сайтов такая нестабильная связь означает тупик — ошибка браузера сообщает пользователю, что он в автономном режиме. А что, если бы ваш сайт мог полностью избежать этой проблемы и продолжать работать?
Это не какая-то экспериментальная будущая функция. Это возможно уже сейчас с помощью технологии браузера под названием Service Worker. Service Worker действует как скриптовый посредник, находящийся между вашим веб-приложением и сетью. Он может перехватывать запросы до того, как они дойдут до сервера, и сам отвечать на них с использованием локально хранимых файлов, что позволяет вашему сайту продолжать работать даже при полном отсутствии связи.
Этот трюк не только предоставляет удобный резервный вариант, но и значительно сокращает время загрузки, делая приложение гораздо более устойчивым к проблемам сети. И хотя это звучит сложно, на самом деле настройка довольно проста.
Что делает этот трюк возможным: Service Workers в сочетании с Cache API
Для реализации этого совместно используются два функционала браузера:
- Service Worker: фоновый скрипт, который работает независимо от основного потока страницы и выполняет функции сетевого слоя.
- Cache API: встроенный интерфейс браузера, позволяющий программно хранить и извлекать ресурсы, похоже на хранилище в формате «ключ-значение». Именно здесь хранятся HTML, CSS, JavaScript, изображения и другие ресурсы, необходимые вашему сайту.
Вот общий алгоритм работы: при первом посещении вашего сайта с подключением к Интернету Service Worker устанавливается и загружает важные файлы в свой кэш. После этого каждый сетевой запрос вашей страницы сначала проходит через Service Worker. Когда у посетителя прерывается подключение, работник отвечает, используя уже сохраненные в кэше данные, вместо того чтобы пытаться — и безуспешно — связаться с сервером, благодаря чему страница все равно отображается практически мгновенно.
Шаг 1: Написание скрипта Service Worker
Начните с создания файла под названием sw.js в корне вашего проекта. Именно этот скрипт отвечает за установку кэша и перехват будущих запросов.
// sw.js
const CACHE_NAME = 'my-website-cache-v1';
const urlsToCache = [
'/',
'/index.html',
'/styles.css',
'/script.js',
'/images/logo.png'
];
// The 'install' event is fired when the service worker is first installed.
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
// The 'fetch' event is fired for every network request.
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
// If the request is in the cache, serve the cached version.
if (response) {
console.log('Serving from cache:', event.request.url);
return response;
}
// Otherwise, fetch from the network.
console.log('Fetching from network:', event.request.url);
return fetch(event.request);
})
);
});
Этот файл в основном отслеживает два события жизненного цикла:
install: здесь открывается кэш с указанным именем, в который добавляется список файлов, которые необходимо иметь в доступе даже без сетевого подключения.fetch: это событие срабатывает при каждом запросе, отправляемом страницей. Рабочий процесс проверяет, существует ли соответствующий ответ уже в кэше; если да, возвращается этот кэшированный экземпляр, а если нет — запрос как обычно отправляется в сеть.
Шаг 2: Регистрация рабочего процесса из вашего приложения
После того как скрипт рабочего процесса создан, браузеру всё ещё нужно указать, как им пользоваться. Добавьте следующий фрагмент в ваш основной файл скриптов или вставьте его внутрь тега <script> в вашем HTML.
// Register the service worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('Service Worker registered successfully:', registration);
})
.catch(error => {
console.error('Service Worker registration failed:', error);
});
});
}
В этом блоке сначала проверяется, поддерживает ли текущий браузер API Service Worker, и если да, происходит регистрация вашего файла sw.js. Обратите внимание на путь регистрации: файл /sw.js должен находиться в корне вашего сайта, поскольку Service Worker может управлять только теми страницами, которые находятся в пределах директории, откуда он зарегистрирован.
Проверка работоспособности
Чтобы увидеть, как это работает на практике, откройте свой сайт в браузере, поддерживающем Service Workers — Chrome, Firefox и Edge все подходят.
- Откройте инструменты разработчика браузера (F12 или Ctrl+Shift+I).
- Перейдите в панель Application.
- В боковой панели найдите раздел Service Workers. Ваш файл
sw.jsдолжен отображаться там как активный.
Если всё настроено правильно, страница загрузится сразу даже без доступа в сеть. Результаты работы консоли в инструментах разработчика подтвердят, что запросы перехватываются и обрабатываются непосредственно из кэша, а не через сеть.
Расширение подхода: альтернативные стратегии кэширования
Описанный выше подход называется стратегией сначала кэш, затем сеть — она отлично подходит для ресурсов, которые редко меняются, таких как статические изображения или собранные скрипты. Однако Service Workers не ограничиваются только этим подходом; существует ещё несколько распространенных стратегий:
- Сначала сеть, затем кэш: подходит для контента, который часто меняется и должен оставаться актуальным. Рабочий процесс сначала пытается получить данные из сети, и только в случае неудачи запроса, например из-за плохого соединения, переходит к использованию данных из кэша.
- Использование устаревших данных до обновления: рабочий процесс немедленно отвечает с уже находящимися в кэше данными для ускорения работы, одновременно отправляя в фоновом режиме запрос в сеть для обновления кэша при следующей загрузке страницы. Это обеспечивает быстрые ответы сейчас и обновленный контент вскоре после этого.
Овладение этим базовым подходом к работе в офлайн-режиме также помогает создавать полноценные прогрессивные веб-приложения, где поддержка работы в офлайн-режиме сочетается с такими функциями, как уведомления и возможность установки сайта на главный экран устройства как нативного приложения.
Добавление этого шаблона в ваш проект — это относительно небольшие усилия в обмен на значимую выгоду: вместо того чтобы неработающее соединение полностью нарушало работу приложения, ваши пользователи едва замечают перерыв.