Service Workers: кэширование, офлайн-доступ, push-уведомления

Что такое Service Worker и зачем он нужен? 🦸

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

Ключевые возможности:

  • 📦 Кэширование — сохраняет файлы для быстрой загрузки
  • 🚫 Офлайн-режим — позволяет работать без интернета
  • 🔔 Push-уведомления — отправляет сообщения даже при закрытом сайте
  • 🔄 Фоновые синхронизации — выполняет задачи, когда соединение восстановлено

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

Прежде чем использовать Service Worker, его нужно зарегистрировать в основном скрипте приложения:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', async () => {
    try {
      const registration = await navigator.serviceWorker.register('/sw.js');
      console.log('ServiceWorker registration successful', registration);
    } catch (error) {
      console.log('ServiceWorker registration failed:', error);
    }
  });
}

💡 Всегда проверяйте поддержку Service Worker в браузере! Не все старые браузеры поддерживают эту технологию.


Жизненный цикл Service Worker

  1. Регистрация — браузер загружает SW-файл
  2. Установка — вызывается событие install
  3. Активация — вызывается событие activate
  4. Готов к работе — может перехватывать fetch-запросы
// sw.js
const CACHE_NAME = 'my-site-cache-v1';
const urlsToCache = [
  '/',
  '/styles/main.css',
  '/script/main.js',
  '/images/logo.png'
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => {
        return cache.addAll(urlsToCache);
      })
  );
});

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

1. Cache First (Offline First)

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
        return response || fetch(event.request);
      })
  );
});

2. Network First

self.addEventListener('fetch', event => {
  event.respondWith(
    fetch(event.request)
      .catch(() => caches.match(event.request))
  );
});

3. Stale-While-Revalidate

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(cachedResponse => {
        const fetchPromise = fetch(event.request)
          .then(networkResponse => {
            caches.open(CACHE_NAME)
              .then(cache => cache.put(event.request, networkResponse));
            return networkResponse.clone();
          });
        return cachedResponse || fetchPromise;
      })
  );
});

Push-уведомления 🔔

Для работы push-уведомлений нужны два компонента: 1. Push API — получает сообщения от сервера 2. Notifications API — отображает уведомления

// Подписка на push-сообщения
self.addEventListener('push', event => {
  const title = 'У вас новое сообщение!';
  const options = {
    body: event.data.text(),
    icon: '/images/icon.png',
    badge: '/images/badge.png'
  };

  event.waitUntil(
    self.registration.showNotification(title, options)
  );
});

// Обработка клика по уведомлению
self.addEventListener('notificationclick', event => {
  event.notification.close();
  event.waitUntil(
    clients.openWindow('https://example.com/notifications')
  );
});

Фоновые синхронизации ⏳

Позволяют отложить задачи до восстановления соединения:

// Регистрация синхронизации
navigator.serviceWorker.ready.then(registration => {
  registration.sync.register('sync-data');
});

// Обработка в SW
self.addEventListener('sync', event => {
  if (event.tag === 'sync-data') {
    event.waitUntil(sendDataToServer());
  }
});

async function sendDataToServer() {
  // Логика отправки данных
}

Лучшие практики работы с Service Worker

  • 🧹 Регулярно очищайте старые кэши
  • 🔄 Обновляйте SW-файл при изменении ресурсов
  • 🔍 Проверяйте кэш в DevTools → Application → Service Workers
  • 🚀 Используйте Workbox для упрощения работы (библиотека от Google)
// Пример очистки старых кэшей
self.addEventListener('activate', event => {
  const cacheWhitelist = ['my-site-cache-v2'];
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (!cacheWhitelist.includes(cacheName)) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

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

Скрыть рекламу навсегда

🎥 YouTube: программирование простым языком

Канал, где я спокойно и по шагам объясняю сложные темы — без заумных терминов и лишней теории.

Подходит, если раньше «не заходило», но хочется наконец понять.

▶️ Смотреть курсы на YouTube