Более свежие работники сферы обслуживания по умолчанию

вр; доктор

Начиная с 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 » и « Лучшие методы кэширования и ошибки максимального возраста », написанные Джейком Арчибальдом, рекомендуются к прочтению всем разработчикам, которые развертывают что-либо в Интернете.