Область видимости Service Worker: параметр scope

В JavaScript при работе с Service Worker ключевым аспектом является область видимости (scope). Она определяет, какие сетевые запросы веб-приложения будут перехватываться конкретным Service Worker. Понимание и корректная настройка scope критически важны для эффективного кэширования ресурсов и управления стратегиями обновления.


Основы параметра scope

scope задаётся при регистрации Service Worker через метод navigator.serviceWorker.register():

navigator.serviceWorker.register('/sw.js', { scope: '/app/' });

Ключевые моменты:

  • Путь относительно корня сайта: /app/ означает, что Service Worker будет контролировать все запросы, URL которых начинаются с /app/.
  • По умолчанию: если scope не указан, Service Worker получает область видимости равную каталогу, где находится файл скрипта Service Worker. Например, '/sw.js' → область видимости '/' будет / только если файл лежит в корне, иначе — каталог, где размещён sw.js.
  • Запрещён переход выше корневого каталога: невозможно указать область видимости выше корневой директории сайта (/).

Влияние scope на перехват запросов

Service Worker перехватывает только запросы внутри своей области видимости. Запросы вне scope будут игнорироваться:

// Service Worker с scope '/app/'
fetch('/app/data.json'); // перехватывается
fetch('/other/data.json'); // не перехватывается

Это важно при проектировании архитектуры веб-приложения:

  • Если один Service Worker отвечает за весь сайт, scope обычно /.
  • Для отдельных модулей или страниц можно создавать локальные Service Worker с scope ограниченным нужным каталогом.

Связь scope и sw-precache

Библиотека sw-precache автоматически генерирует файл Service Worker с кэшированием указанных ресурсов. При использовании scope важно учитывать следующие моменты:

  1. Регистрируемый Service Worker должен находиться в пределах области видимости:
// sw-precache сгенерировал sw.js
navigator.serviceWorker.register('/app/sw.js', { scope: '/app/' });
  1. Кэшируемые ресурсы (staticFileGlobs) должны быть внутри scope. Если ресурсы находятся вне области видимости, Service Worker не сможет их контролировать и обновлять.
module.exports = {
  staticFileGlobs: [
    'app/**/*.html',
    'app/**/*.css',
    'app/**/*.js'
  ],
  stripPrefix: 'app/',
  navigateFallback: '/app/index.html'
};

Изменение scope после регистрации

Область видимости определяется только при регистрации. Изменить её на лету невозможно без повторной регистрации Service Worker:

navigator.serviceWorker.register('/sw.js', { scope: '/new-scope/' })
  .then(() => console.log('SW с новым scope зарегистрирован'));

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


Практические рекомендации

  • Минимизировать область видимости для модульных приложений, чтобы один Service Worker не перехватывал лишние запросы.
  • Использовать scope, соответствующий корневой папке приложения при глобальном кэшировании.
  • Следить за расположением файла sw.js, так как scope не может быть выше его пути. Например, /app/sw.jsscope не может быть /.
  • Комбинировать с navigateFallback в sw-precache для SPA, чтобы все маршруты в пределах scope корректно обслуживались Service Worker.

Пример конфигурации sw-precache с учетом scope

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

swPrecache.write('app/sw.js', {
  staticFileGlobs: [
    'app/**/*.html',
    'app/**/*.css',
    'app/**/*.js',
    'app/images/**/*'
  ],
  stripPrefix: 'app/',
  navigateFallback: '/index.html',
  runtimeCaching: [{
    urlPattern: /\/api\/.*$/,
    handler: 'networkFirst'
  }]
});

// Регистрация с правильным scope
navigator.serviceWorker.register('/app/sw.js', { scope: '/app/' })
  .then(function(reg) {
    console.log('Service Worker зарегистрирован с scope:', reg.scope);
  });

В этом примере:

  • Service Worker обслуживает все URL, начинающиеся с /app/.
  • Все статические файлы и API-запросы внутри scope могут кэшироваться.
  • navigateFallback гарантирует корректную работу SPA маршрутов.

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