вр; доктор
Начиная с Chrome 68, HTTP-запросы, проверяющие наличие обновлений сценария сервисного работника, больше не будут по умолчанию выполняться HTTP-кешем . Это позволяет обойти распространенную проблему разработчиков , когда установка непреднамеренного заголовка Cache-Control
в скрипте сервис-воркера может привести к задержке обновлений.
Если вы уже отказались от HTTP-кеширования для вашего сценария /service-worker.js
, предоставив его с помощью Cache-Control: max-age=0
, вы не увидите никаких изменений из-за нового поведения по умолчанию.
Кроме того, начиная с Chrome 78, побайтовое сравнение будет применяться к сценариям, загруженным в сервис-воркер через importScripts()
. Любое изменение, внесенное в импортированный скрипт, запускает поток обновления сервис-воркера , точно так же, как это происходит при изменении сервис-воркера верхнего уровня.
Фон
Каждый раз, когда вы переходите на новую страницу, находящуюся в области действия сервис-воркера, явно вызываете метод registration.update()
из JavaScript, или когда сервис-воркер «пробуждается» посредством события push
или sync
, браузер параллельно запрашивает ресурс JavaScript, который изначально был передан в вызов navigator.serviceWorker.register()
для поиска обновлений сценария сервисного работника.
Для целей этой статьи предположим, что его URL-адрес — /service-worker.js
и что он содержит единственный вызов importScripts()
, который загружает дополнительный код, выполняемый внутри сервис-воркера:
// Inside our /service-worker.js file:
importScripts('path/to/import.js');
// Other top-level code goes here.
Что меняется?
До Chrome 68 запрос на обновление /service-worker.js
выполнялся через HTTP-кеш (как и большинство операций выборки). Это означало, что если скрипт изначально был отправлен с Cache-Control: max-age=600
, обновления в течение следующих 600 секунд (10 минут) не поступали бы в сеть, поэтому пользователь мог не получить самую актуальную версию. работника службы. Однако если max-age
превышает 86400 (24 часа), он будет считаться равным 86400, чтобы пользователи не оставались навсегда с определенной версией.
Начиная с версии 68, кэш HTTP будет игнорироваться при запросе обновлений сценария Service Worker, поэтому в существующих веб-приложениях может наблюдаться увеличение частоты запросов к их сценарию Service Worker. Запросы на importScripts
по-прежнему будут проходить через HTTP-кеш. Но это всего лишь значение по умолчанию — доступен новый вариант регистрации updateViaCache
, который предлагает контроль над этим поведением.
обновлениеViaCache
Разработчики теперь могут передавать новую опцию при вызове navigator.serviceWorker.register()
: параметр updateViaCache
. Он принимает одно из трех значений: 'imports'
, 'all'
или 'none'
.
Значения определяют, будет ли и каким образом использоваться стандартный HTTP-кеш браузера при выполнении HTTP-запроса для проверки наличия обновленных ресурсов Service Worker.
Если установлено значение
'imports'
, HTTP-кеш никогда не будет проверяться на наличие обновлений сценария/service-worker.js
, но будет проверяться при извлечении любых импортированных сценариев (path/to/import.js
в нашем примере). . Это значение по умолчанию, и оно соответствует поведению, начиная с Chrome 68.Если установлено значение
'all'
, кеш HTTP будет использоваться при выполнении запросов как для скрипта верхнего уровня/service-worker.js
, так и для любых скриптов, импортированных внутри сервис-воркера, напримерpath/to/import.js
. Этот параметр соответствует предыдущему поведению в Chrome до Chrome 68.Если установлено значение
'none'
, кеш HTTP не будет использоваться при выполнении запросов ни к/service-worker.js
верхнего уровня, ни к любым импортированным сценариям, таким как гипотетическийpath/to/import.js
.
Например, следующий код зарегистрирует сервисного работника и гарантирует, что кеш HTTP никогда не будет использоваться при проверке обновлений сценария /service-worker.js
или любых сценариев, на которые ссылаются через importScripts()
внутри /service-worker.js
:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js', {
updateViaCache: 'none',
// Optionally, set 'scope' here, if needed.
});
}
Проверяет наличие обновлений импортированных скриптов.
До Chrome 78 любой сценарий сервисного работника, загруженный через importScripts()
извлекался только один раз (сначала проверяясь по HTTP-кешу или через сеть, в зависимости от конфигурации updateViaCache
). После этого первоначального извлечения он будет храниться внутри браузера и никогда не будет получен повторно.
Единственный способ заставить уже установленный сервис-воркер принять изменения в импортированном скрипте — это изменить URL-адрес скрипта, обычно либо путем добавления значения semver (например, importScripts('https://example.com/v1.1.0/index.js')
) или включив хеш содержимого (например, importScripts('https://example.com/index.abcd1234.js')
). Побочным эффектом изменения импортированного URL-адреса является изменение содержимого сценария Service Worker верхнего уровня, что, в свою очередь, запускает поток обновления Service Worker .
Начиная с Chrome 78, каждый раз, когда выполняется проверка обновлений для файла Service Worker верхнего уровня, одновременно будут выполняться проверки, чтобы определить, изменилось ли содержимое каких-либо импортированных скриптов. В зависимости от используемых заголовков Cache-Control
эти проверки импортированных сценариев могут выполняться HTTP-кешем, если для updateViaCache
установлено значение 'all'
или 'imports'
(значение по умолчанию), или проверки могут выполняться непосредственно в сети, если Для updateViaCache
установлено значение 'none'
.
Если проверка обновлений для импортированного скрипта приводит к побайтовой разнице по сравнению с тем, что было ранее сохранено сервисным работником, это, в свою очередь, запускает полный поток обновлений сервисного работника, даже если файл сервисного работника верхнего уровня остается одинаковый.
Поведение Chrome 78 соответствует тому, что Firefox реализовал несколько лет назад в Firefox 56. Safari уже реализует такое поведение.
Что нужно сделать разработчикам?
Если вы фактически отказались от HTTP-кеширования для вашего сценария /service-worker.js
, предоставив его с помощью Cache-Control: max-age=0
(или аналогичного значения), то вы не увидите никаких изменений из-за новое поведение по умолчанию.
Если вы обслуживаете свой скрипт /service-worker.js
с включенным HTTP-кэшированием, намеренно или потому, что это просто значение по умолчанию для вашей среды хостинга , вы можете начать наблюдать рост дополнительных HTTP-запросов для /service-worker.js
сделанных против вашего сервер — это запросы, которые раньше выполнялись HTTP-кешем. Если вы хотите и дальше позволять значению заголовка Cache-Control
влиять на актуальность вашего /service-worker.js
, вам нужно будет начать явно устанавливать updateViaCache: 'all'
при регистрации вашего сервисного работника.
Учитывая, что в старых версиях браузера может быть длинный хвост пользователей, по-прежнему рекомендуется продолжать устанавливать HTTP-заголовок Cache-Control: max-age=0
в сценариях сервис-воркеров, даже если новые браузеры могут их игнорировать.
Разработчики могут использовать эту возможность, чтобы решить, хотят ли они сейчас явно исключить свои импортированные сценарии из HTTP-кэширования, и при необходимости добавить updateViaCache: 'none'
в свою регистрацию сервис-воркера.
Обслуживание импортированных скриптов
Начиная с Chrome 78, разработчики могут видеть больше входящих HTTP-запросов к ресурсам, загружаемым через importScripts()
, поскольку теперь они будут проверяться на наличие обновлений.
Если вы хотите избежать этого дополнительного HTTP-трафика, установите долгоживущие заголовки Cache-Control
при обслуживании сценариев, которые включают semver или хэши в свои URL-адреса, и полагайтесь на поведение updateViaCache
по умолчанию для 'imports'
.
В качестве альтернативы, если вы хотите, чтобы ваши импортированные скрипты проверялись на наличие частых обновлений, убедитесь, что вы либо обслуживаете их с помощью Cache-Control: max-age=0
, либо используете updateViaCache: 'none'
.
Дальнейшее чтение
« Жизненный цикл Service Worker » и « Лучшие методы кэширования и ошибки максимального возраста », написанные Джейком Арчибальдом, рекомендуются к прочтению всем разработчикам, которые развертывают что-либо в Интернете.