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

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

Основные функции Service Worker:

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

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

Жизненный цикл Service Worker отличается от жизненного цикла обычной веб-страницы и состоит из нескольких этапов:

  1. Регистрация: браузер узнает о существовании скрипта и готовит его к установке.
  2. Установка (Install): Service Worker выполняет первоначальное кэширование ресурсов. Если на этом этапе происходит ошибка, установка прерывается.
  3. Активация (Activate): после успешной установки Service Worker становится активным и получает возможность управлять страницами. Здесь обычно выполняется очистка устаревших кэшей.
  4. Работа (Fetch и другие события): Service Worker перехватывает сетевые запросы и обрабатывает события push, sync и другие.

Использование Sw-precache

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

Установка и базовая конфигурация

npm install sw-precache --save-dev

Для генерации Service Worker используется Node.js скрипт, в котором указываются пути ресурсов, которые нужно кэшировать, и параметры кэширования:

const swPrecache = require('sw-precache');

swPrecache.write('service-worker.js', {
  staticFileGlobs: [
    'index.html',
    'css/**/*.css',
    'js/**/*.js',
    'images/**/*.{png,jpg,gif,svg}'
  ],
  stripPrefix: 'dist/',
  runtimeCaching: [{
    urlPattern: /\/api\//,
    handler: 'networkFirst'
  }]
});

Ключевые параметры:

  • staticFileGlobs — массив файлов и шаблонов, которые будут закэшированы.
  • stripPrefix — позволяет удалить часть пути из кэша для удобства доступа.
  • runtimeCaching — определяет динамическое кэширование ресурсов, таких как API-запросы. Параметр handler задает стратегию кэширования: networkFirst, cacheFirst, fastest и другие.

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

Sw-precache поддерживает несколько стратегий управления кэшем:

  1. Cache First — сначала проверяется кэш, если ресурс там есть, он возвращается без запроса на сервер. Используется для статических ресурсов, редко изменяющихся.
  2. Network First — запрос сначала идет на сервер. Если сервер недоступен, берется версия из кэша. Подходит для динамического контента.
  3. Fastest — одновременно обращается к кэшу и серверу, возвращая тот ответ, который приходит первым.

Интеграция с билд-системами

Sw-precache удобно интегрировать с Gulp, Webpack или другими сборщиками:

Пример с Gulp:

const gulp = require('gulp');
const swPrecache = require('sw-precache');

gulp.task('generate-service-worker', function(callback) {
  swPrecache.write('dist/service-worker.js', {
    staticFileGlobs: ['dist/**/*.{html,js,css,png,jpg,gif,svg}'],
    stripPrefix: 'dist/'
  }, callback);
});

Такой подход позволяет автоматически обновлять кэш при сборке проекта и минимизирует ручное вмешательство.

Работа с обновлениями Service Worker

Service Worker обновляется при изменении его файла. Sw-precache генерирует уникальные хэши для ресурсов, что позволяет браузеру корректно определять, какие файлы нужно обновить. Рекомендуется использовать стратегию «cache busting» для всех часто меняющихся файлов, чтобы избежать загрузки устаревших данных.