Внести вклад
Расширенная экосистема
Service Workers и PWA

Файл конфигурации Service Worker

Эта тема описывает свойства файла конфигурации service worker.

Изменение конфигурации

JSON-файл конфигурации ngsw-config.json указывает, какие файлы и data URL Angular service worker должен кэшировать и как обновлять кэшированные файлы и данные. Angular CLI обрабатывает этот файл конфигурации во время ng build.

Все пути к файлам должны начинаться с /, что соответствует каталогу развёртывания — обычно dist/<project-name> в CLI-проектах.

Если не указано иное, шаблоны используют ограниченный* формат glob, который внутри преобразуется в regex:

Форматы glob Подробности
** Совпадает с 0 или более сегментами пути
* Совпадает с 0 или более символами, исключая /
? Совпадает ровно с одним символом, исключая /
префикс ! Помечает шаблон как отрицательный: включаются только файлы, которые не совпадают с шаблоном

Специальные символы нужно экранировать

Обратите внимание: некоторые символы со специальным значением в регулярном выражении не экранируются, а шаблон не оборачивается в ^/$ при внутреннем преобразовании glob в regex.

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

Если нужно буквально совпасть с символом $, экранируйте его сами (через \\$). Например, glob-шаблон /foo/bar/$value даёт несовпадаемое выражение, потому что невозможно иметь строку с символами после её конца.

Шаблон не оборачивается автоматически в ^ и $ при преобразовании в регулярное выражение. Поэтому шаблоны частично совпадают с URL запросов.

Если нужно, чтобы шаблоны совпадали с началом и/или концом URL, добавьте ^/$ сами. Например, glob-шаблон /foo/bar/*.js совпадёт и с .js, и с .json файлами. Чтобы совпадать только с .js, используйте /foo/bar/*.js$.

Примеры шаблонов:

Шаблоны Подробности
/**/*.html Все HTML-файлы
/*.html Только HTML-файлы в корне
!/**/*.map Исключить все sourcemaps

Свойства конфигурации service worker

Следующие разделы описывают каждое свойство файла конфигурации.

appData

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

index

Указывает файл, служащий index-страницей для удовлетворения navigation-запросов. Обычно это /index.html.

assetGroups

Assets — ресурсы, входящие в версию приложения и обновляющиеся вместе с ним. Они могут включать ресурсы, загружаемые с origin страницы, а также сторонние ресурсы с CDN и других внешних URL. Поскольку не все такие внешние URL могут быть известны на этапе сборки, можно сопоставлять URL-шаблоны.

ПОЛЕЗНО: Чтобы service worker обрабатывал ресурсы с других origin, убедитесь, что CORS правильно настроен на сервере каждого origin.

Это поле содержит массив групп assets; каждая определяет набор asset-ресурсов и политику их кэширования.

{
  "assetGroups": [
    {

    },
    {

    }
  ]
}

ПОЛЕЗНО: Когда ServiceWorker обрабатывает запрос, он проверяет группы assets в порядке появления в ngsw-config.json. Первая группа assets, совпавшая с запрошенным ресурсом, обрабатывает запрос.

Рекомендуется ставить более специфичные группы assets выше в списке. Например, группа assets, совпадающая с /foo.js, должна идти перед совпадающей с *.js.

Каждая группа assets задаёт и группу ресурсов, и политику, управляющую ими. Политика определяет, когда ресурсы загружаются и что происходит при обнаружении изменений.

Группы assets следуют TypeScript-интерфейсу:

interface AssetGroup {
  name: string;
  installMode?: 'prefetch' | 'lazy';
  updateMode?: 'prefetch' | 'lazy';
  resources: {
    files?: string[];
    urls?: string[];
  };
  cacheQueryOptions?: {
    ignoreSearch?: boolean;
  };
}

Каждый AssetGroup определяется следующими свойствами.

name

name обязателен. Он идентифицирует эту группу assets между версиями конфигурации.

installMode

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

Значения Подробности
prefetch Указывает Angular service worker загружать каждый перечисленный ресурс при кэшировании текущей версии приложения. Это интенсивно по трафику, но гарантирует доступность ресурсов при запросе, даже если браузер сейчас офлайн.
lazy Не кэширует ресурсы заранее. Вместо этого Angular service worker кэширует только ресурсы, на которые получает запросы. Это режим кэширования по требованию. Ресурсы, которые никогда не запрашивались, не кэшируются. Полезно, например, для изображений разного разрешения — service worker кэширует только подходящие assets для конкретного экрана и ориентации.

По умолчанию — prefetch.

updateMode

Для ресурсов, уже находящихся в кэше, updateMode определяет поведение кэширования при обнаружении новой версии приложения. Любые ресурсы в группе, изменившиеся с предыдущей версии, обновляются в соответствии с updateMode.

Значения Подробности
prefetch Указывает service worker сразу скачать и закэшировать изменённые ресурсы.
lazy Указывает service worker не кэшировать эти ресурсы. Вместо этого он считает их незапрошенными и ждёт повторного запроса перед обновлением. updateMode со значением lazy допустим только если installMode тоже lazy.

По умолчанию — значение, заданное в installMode.

resources

Этот раздел описывает ресурсы для кэширования, разбитые на следующие группы:

Группы ресурсов Подробности
files Списки шаблонов, совпадающих с файлами в каталоге дистрибутива. Это могут быть отдельные файлы или glob-подобные шаблоны, совпадающие с несколькими файлами.
urls Включает и URL, и URL-шаблоны, сопоставляемые во время выполнения. Эти ресурсы не загружаются напрямую и не имеют хешей содержимого, но кэшируются согласно HTTP-заголовкам. Наиболее полезно для CDN вроде Google Fonts.
(Отрицательные glob-шаблоны не поддерживаются, а ? совпадает буквально; то есть не совпадает ни с каким символом, кроме ?.)

cacheQueryOptions

Эти опции изменяют поведение сопоставления запросов. Они передаются в функцию браузера Cache#match. Подробности — на MDN. Сейчас поддерживаются только следующие опции:

Опции Подробности
ignoreSearch Игнорировать query-параметры. По умолчанию false.

dataGroups

В отличие от asset-ресурсов, data-запросы не версионируются вместе с приложением. Они кэшируются по вручную настроенным политикам, более полезным для ситуаций вроде API-запросов и других зависимостей от данных.

Это поле содержит массив data-групп; каждая определяет набор data-ресурсов и политику их кэширования.

{
  "dataGroups": [
    {

    },
    {

    }
  ]
}

ПОЛЕЗНО: Когда ServiceWorker обрабатывает запрос, он проверяет data-группы в порядке появления в ngsw-config.json. Первая data-группа, совпавшая с запрошенным ресурсом, обрабатывает запрос.

Рекомендуется ставить более специфичные data-группы выше в списке. Например, data-группа, совпадающая с /api/foo.json, должна идти перед совпадающей с /api/*.json.

Data-группы следуют этому TypeScript-интерфейсу:

export interface DataGroup {
  name: string;
  urls: string[];
  version?: number;
  cacheConfig: {
    maxSize: number;
    maxAge: string;
    timeout?: string;
    refreshAhead?: string;
    strategy?: 'freshness' | 'performance';
  };
  cacheQueryOptions?: {
    ignoreSearch?: boolean;
  };
}

Каждый DataGroup определяется следующими свойствами.

name

Как и у assetGroups, у каждой data-группы есть name, уникально её идентифицирующий.

urls

Список URL-шаблонов. URL, совпадающие с этими шаблонами, кэшируются по политике этой data-группы. Кэшируются только немутирующие запросы (GET и HEAD).

  • Отрицательные glob-шаблоны не поддерживаются
  • ? совпадает буквально; то есть совпадает только с символом ?

version

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

version даёт механизм указать, что кэшируемые ресурсы обновлены несовместимым образом и что старые записи кэша — из предыдущих версий — следует отбросить.

version — целочисленное поле, по умолчанию 1.

cacheConfig

Следующие свойства определяют политику кэширования совпадающих запросов.

maxSize

Максимальное число записей, или ответов, в кэше.

КРИТИЧНО: Неограниченные кэши могут расти без предела и в итоге превысить квоты хранилища, что приведёт к вытеснению.

maxAge

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

Суффиксы Подробности
d Дни
h Часы
m Минуты
s Секунды
u Миллисекунды

Например, строка 3d12h кэширует контент до трёх с половиной дней.

timeout

Эта строка длительности задаёт сетевой таймаут. Сетевой таймаут — сколько Angular service worker ждёт ответа сети, прежде чем использовать закэшированный ответ, если это настроено. timeout — строка длительности со следующими суффиксами единиц:

Суффиксы Подробности
d Дни
h Часы
m Минуты
s Секунды
u Миллисекунды

Например, строка 5s30u означает пять секунд и 30 миллисекунд сетевого таймаута.

refreshAhead

Эта строка длительности задаёт, за сколько до истечения закэшированного ресурса Angular service worker должен проактивно попытаться обновить ресурс из сети. Длительность refreshAhead — необязательная конфигурация, определяющая, за сколько до истечения закэшированного ответа service worker должен инициировать запрос на обновление ресурса из сети.

Суффиксы Подробности
d Дни
h Часы
m Минуты
s Секунды
u Миллисекунды

Например, строка 1h30m означает один час и 30 минут до времени истечения.

strategy

Angular service worker может использовать одну из двух стратегий кэширования для data-ресурсов.

Стратегии кэширования Подробности
performance По умолчанию; оптимизирует ответы на максимальную скорость. Если ресурс есть в кэше, используется закэшированная версия, сетевой запрос не делается. Это допускает некоторую устарелость в зависимости от maxAge в обмен на лучшую производительность. Подходит для ресурсов, которые редко меняются; например, аватары пользователей.
freshness Оптимизирует актуальность данных, предпочтительно загружая запрошенные данные из сети. Только если сеть истекает по timeout, запрос откатывается к кэшу. Полезно для ресурсов, которые часто меняются; например, балансы счетов.

ПОЛЕЗНО: Также можно эмулировать третью стратегию, staleWhileRevalidate, которая возвращает закэшированные данные, если они доступны, но также загружает свежие данные из сети в фоне для следующего раза. Чтобы использовать эту стратегию, задайте strategy в freshness и timeout в 0u в cacheConfig.

По сути это делает следующее:

  1. Сначала попытаться загрузить из сети.
  2. Если сетевой запрос не завершается сразу, то есть после таймаута 0 мс, игнорировать возраст кэша и откатиться к закэшированному значению.
  3. Когда сетевой запрос завершится, обновить кэш для будущих запросов.
  4. Если ресурса нет в кэше, всё равно ждать сетевой запрос.
cacheOpaqueResponses

Должен ли Angular service worker кэшировать opaque-ответы.

Если не указано, значение по умолчанию зависит от настроенной стратегии data-группы:

Стратегии Подробности
Группы со стратегией freshness Значение по умолчанию — true, service worker кэширует opaque-ответы. Эти группы запрашивают данные каждый раз и откатываются к закэшированному ответу только офлайн или на медленной сети. Поэтому неважно, кэширует ли service worker ответ с ошибкой.
Группы со стратегией performance Значение по умолчанию — false, service worker не кэширует opaque-ответы. Эти группы продолжали бы возвращать закэшированный ответ до истечения maxAge, даже если ошибка была из-за временной сетевой или серверной проблемы. Поэтому кэширование ответа с ошибкой было бы проблематично.

Замечание об opaque-ответах

Если вы не знакомы: opaque-ответ — особый тип ответа при запросе ресурса с другого origin, который не возвращает CORS-заголовки. Одна из характеристик opaque-ответа — service worker не может прочитать его статус, то есть не может проверить, успешен ли запрос. Подробнее — в Introduction to fetch().

Если реализовать CORS нельзя — например, вы не контролируете origin — предпочитайте стратегию freshness для ресурсов, дающих opaque-ответы.

cacheQueryOptions

Подробности — в assetGroups.

Этот необязательный раздел позволяет задать пользовательский список URL, которые будут перенаправлены на index-файл.

Обработка navigation-запросов

ServiceWorker перенаправляет navigation-запросы, не совпадающие ни с одной группой asset или data, на указанный index-файл. Запрос считается navigation-запросом, если:

  • Его methodGET
  • Его modenavigation
  • Он принимает ответ text/html, что определяется значением заголовка Accept
  • Его URL соответствует следующим критериям:
    • URL не должен содержать расширение файла (то есть .) в последнем сегменте пути
    • URL не должен содержать __

ПОЛЕЗНО: Чтобы настроить, отправляются ли navigation-запросы в сеть, см. разделы navigationRequestStrategy и applicationMaxAge.

Сопоставление URL navigation-запросов

Хотя эти критерии по умолчанию подходят в большинстве случаев, иногда желательно настроить другие правила. Например, можно игнорировать конкретные маршруты, не входящие в Angular-приложение, и пропускать их на сервер.

Это поле содержит массив URL и glob-подобных URL-шаблонов, сопоставляемых во время выполнения. Оно может содержать и отрицательные шаблоны (то есть начинающиеся с !), и неотрицательные шаблоны и URL.

Только запросы, чьи URL совпадают с любым из неотрицательных URL/шаблонов и ни с одним из отрицательных, считаются navigation-запросами. Query URL игнорируется при сопоставлении.

Если поле опущено, по умолчанию:

[
  '/**', // Include all URLs.
  '!/**/*.*', // Exclude URLs to files (containing a file extension in the last segment).
  '!/**/*__*', // Exclude URLs containing `__` in the last segment.
  '!/**/*__*/**', // Exclude URLs containing `__` in any other segment.
];

Это необязательное свойство позволяет настроить, как service worker обрабатывает navigation-запросы:

{
  "navigationRequestStrategy": "freshness"
}
Возможные значения Подробности
'performance' Настройка по умолчанию. Отдаёт указанный index-файл, который обычно закэширован.
'freshness' Пропускает запросы в сеть и откатывается к поведению performance офлайн. Это значение полезно, когда сервер перенаправляет navigation-запросы в другое место кодом статуса HTTP-редиректа 3xx. Причины использования:
  • Редирект на сайт аутентификации, когда аутентификация не обрабатывается приложением
  • Редирект конкретных URL, чтобы не ломать существующие ссылки/закладки после редизайна сайта
  • Редирект на другой сайт, например страницу статуса сервера, пока страница временно недоступна

ВАЖНО: Стратегия freshness обычно приводит к большему числу запросов к серверу, что может увеличить задержку ответа. Рекомендуется по возможности использовать стратегию performance по умолчанию.

applicationMaxAge

Это необязательное свойство позволяет настроить, как долго service worker будет кэшировать любые запросы. В пределах maxAge файлы отдаются из кэша. После него все запросы отдаются только из сети, включая asset- и data-запросы.