Перейти к содержанию

Конфигурация работника службы

📅 28.02.2022

В этой теме описываются свойства файла конфигурации работника службы.

Предварительные условия

Базовое понимание следующего:

Конфигурационный файл ngsw-config.json определяет, какие файлы и URL данных должен кэшировать сервисный работник Angular и как он должен обновлять кэшированные файлы и данные. Angular CLI обрабатывает конфигурационный файл во время ng build.

Вручную, обработайте его с помощью инструмента ngsw-config (где <имя проекта> — имя собираемого проекта):

1
./node_modules/.bin/ngsw-config ./dist/<project-name> ./ngsw-config.json [/base/href]

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

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

Glob formats Details
** Совпадает с 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 Исключить все карты источников

Свойства конфигурации работника службы

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

appData

Этот раздел позволяет вам передать любые данные, которые описывают данную конкретную версию приложения. Служба SwUpdate включает эти данные в уведомления об обновлении.

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

index

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

assetGroups

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

Поскольку не все такие внешние URL могут быть известны на момент сборки, можно сопоставить шаблоны URL.

Чтобы работник службы мог обрабатывать ресурсы, загруженные из разных источников, убедитесь, что CORS правильно настроен на сервере каждого источника.

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "assetGroups": [
    {
      
    },
    {
      
    }
  ]
}

Когда ServiceWorker обрабатывает запрос, он проверяет группы активов в том порядке, в котором они появляются в файле ngsw-config.json. Первая группа активов, которая соответствует запрашиваемому ресурсу, обрабатывает запрос.

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

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

Группы активов следуют интерфейсу Typescript, показанному здесь:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
interface AssetGroup {
    name: string;
    installMode?: 'prefetch' | 'lazy';
    updateMode?: 'prefetch' | 'lazy';
    resources: {
        files?: string[];
        urls?: string[];
    };
    cacheQueryOptions?: {
        ignoreSearch?: boolean;
    };
}

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

имя.

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

installMode.

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

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

По умолчанию используется prefetch.

updateMode

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

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

По умолчанию принимает значение, на которое установлен installMode.

resources

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

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

cacheQueryOptions

Эти опции используются для изменения поведения при подборе запросов. Они передаются в функцию браузера Cache#match.

Подробности смотрите в MDN.

В настоящее время поддерживаются только следующие опции:

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

dataGroups

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "dataGroups": [
    {
      
    },
    {
      
    }
  ]
}

Когда ServiceWorker обрабатывает запрос, он проверяет группы данных в том порядке, в котором они появляются в файле ngsw-config.json. Первая группа данных, которая соответствует запрашиваемому ресурсу, обрабатывает запрос.

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

Группы данных следуют этому интерфейсу Typescript:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
export interface DataGroup {
    name: string;
    urls: string[];
    version?: number;
    cacheConfig: {
        maxSize: number;
        maxAge: string;
        timeout?: string;
        strategy?: 'freshness' | 'performance';
    };
    cacheQueryOptions?: {
        ignoreSearch?: boolean;
    };
}

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

name

Подобно assetGroups, каждая группа данных имеет name, которое уникально идентифицирует ее.

urls

Список шаблонов URL. URL, соответствующие этим шаблонам, кэшируются в соответствии с политикой этой группы данных.

Кэшируются только не мутирующие запросы (GET и HEAD).

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

version

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

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

Поле version является целочисленным и по умолчанию равно 1.

cacheConfig

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

maxSize

Обязательно

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

maxAge

Необходимо

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

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

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

timeout

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

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

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

strategy

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

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

Вы также можете эмулировать третью стратегию, staleWhileRevalidate, которая возвращает кэшированные данные, если они доступны, но также забирает свежие данные из сети в фоновом режиме для следующего раза. Для использования этой стратегии установите strategy в freshness и timeout в cacheConfig в 0u.

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

  1. Сначала попытаться получить данные из сети.

  2. Если сетевой запрос не завершается немедленно, то есть после тайм-аута в 0 мс, игнорировать возраст кэша и вернуться к кэшированному значению.

  3. После завершения сетевого запроса обновите кэш для будущих запросов.

  4. Если ресурс не существует в кэше, все равно дождитесь сетевого запроса.

cacheOpaqueResponses

Должен ли работник службы Angular кэшировать непрозрачные ответы или нет.

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

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

Комментарий к непрозрачным ответам

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

Более подробную информацию смотрите в Введение в fetch().

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

cacheQueryOptions

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

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

Обработка навигационных запросов

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

  • Его методGET.

  • Его режимnavigation.

  • Он принимает ответ text/html, что определяется значением заголовка Accept.

  • Его URL соответствует следующим критериям:

    • URL не должен содержать расширение файла (то есть, .) в последнем сегменте пути.

    • URL не должен содержать __

Чтобы настроить, будут ли навигационные запросы передаваться в сеть или нет, смотрите раздел navigationRequestStrategy.

Соответствие URL-адресов навигационных запросов

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

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

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

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

1
2
3
4
5
6
[
    '/**', // Include all URLs.
    '!/**/*.*', // Exclude URLs to files.
    '!/**/*__*', // Exclude URLs containing `__` in the last segment.
    '!/**/*__*/**', // Exclude URLs containing `__` in any other segment.
];

Это необязательное свойство позволяет вам настроить, как работник службы обрабатывает навигационные запросы:

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

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

Комментарии