Главная / Статьи

Включите поддержку офлайн-режима в веб-приложениях с помощью Service Workers

Рабочие процессы и API кэширования позволяют сайту загружаться мгновенно и продолжать работать в офлайн-режиме. Написание кода рабочего процесса, его регистрация и выбор стратегий кэширования.

Издатель: REACTAPP.TOP5 мин чтения1098 слов

Источники: ☕ JavaScript Hack That Makes Any Website Work Offline

Представьте, что кто-то просматривает ваш сайт в поезде, при этом сигнал время от времени пропадает на несколько секунд. На большинстве веб-сайтов такая нестабильная связь означает тупик — ошибка браузера сообщает пользователю, что он в автономном режиме. А что, если бы ваш сайт мог полностью избежать этой проблемы и продолжать работать?

Это не какая-то экспериментальная будущая функция. Это возможно уже сейчас с помощью технологии браузера под названием Service Worker. Service Worker действует как скриптовый посредник, находящийся между вашим веб-приложением и сетью. Он может перехватывать запросы до того, как они дойдут до сервера, и сам отвечать на них с использованием локально хранимых файлов, что позволяет вашему сайту продолжать работать даже при полном отсутствии связи.

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

Что делает этот трюк возможным: Service Workers в сочетании с Cache API

Для реализации этого совместно используются два функционала браузера:

  1. Service Worker: фоновый скрипт, который работает независимо от основного потока страницы и выполняет функции сетевого слоя.
  2. 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 должен отображаться там как активный.
  • Нажмите на Cache Storage, чтобы убедиться, что ваша именованная кэш-память существует и содержит указанные файлы.
  • Отметьте галочкой поле «Offline», расположенное в верхней части раздела Service Worker.
  • Перезагрузите страницу.
  • Если всё настроено правильно, страница загрузится сразу даже без доступа в сеть. Результаты работы консоли в инструментах разработчика подтвердят, что запросы перехватываются и обрабатываются непосредственно из кэша, а не через сеть.

    Расширение подхода: альтернативные стратегии кэширования

    Описанный выше подход называется стратегией сначала кэш, затем сеть — она отлично подходит для ресурсов, которые редко меняются, таких как статические изображения или собранные скрипты. Однако Service Workers не ограничиваются только этим подходом; существует ещё несколько распространенных стратегий:

    • Сначала сеть, затем кэш: подходит для контента, который часто меняется и должен оставаться актуальным. Рабочий процесс сначала пытается получить данные из сети, и только в случае неудачи запроса, например из-за плохого соединения, переходит к использованию данных из кэша.
    • Использование устаревших данных до обновления: рабочий процесс немедленно отвечает с уже находящимися в кэше данными для ускорения работы, одновременно отправляя в фоновом режиме запрос в сеть для обновления кэша при следующей загрузке страницы. Это обеспечивает быстрые ответы сейчас и обновленный контент вскоре после этого.

    Овладение этим базовым подходом к работе в офлайн-режиме также помогает создавать полноценные прогрессивные веб-приложения, где поддержка работы в офлайн-режиме сочетается с такими функциями, как уведомления и возможность установки сайта на главный экран устройства как нативного приложения.

    Добавление этого шаблона в ваш проект — это относительно небольшие усилия в обмен на значимую выгоду: вместо того чтобы неработающее соединение полностью нарушало работу приложения, ваши пользователи едва замечают перерыв.