Каковы недостатки использования skipWaiting и clientsClaim с Workbox?

По умолчанию для skipWaiting в Workbox установлено значение false. Предполагая, что вы только используете для кэширования сервис-воркера, созданного Workbox, есть ли недостатки в установке этого значения в true? Без этого следующая сборка вашего приложения будет поставлять обновленные URL-адреса ресурсов (из webpack). Эти URL-адреса будут обновлены в манифесте предварительного кеширования сервис-воркера, но без skipWaiting обновленный сервис-воркер не будет активирован, чтобы воспользоваться ими, пока пользователь не закроет свой браузер и не откроется снова.

Эти обновленные ресурсы будут загружены правильно (webpack загрузит ресурсы с новыми хэш-значениями в них), но они никогда не будут кэшироваться до тех пор, пока пользователь снова не закроет все открытые браузеры, в которых запущен сервис-воркер. , и снова открывается. В таких обстоятельствах есть ли причина не просто установить skipWaiting в значение true?

В качестве связанного вопроса: что именно контролирует clientsClaim? Вышеупомянутая проблема решается простым включением skipWaiting; так что же делает clientsClaim?


person Adam Rackis    schedule 06.08.2018    source источник


Ответы (1)


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

Эти концепции также объясняются более подробно с точки зрения использования create-react-app в этом обращении внимания при ленивой загрузке Обсуждение и микросайт.

Реализация Workbox

Workbox использует обработчик событий install для кэширования новых или обновленных записей в манифесте предварительного кеширования (добавляя параметр запроса __WB_REVISION__ к URL-адресам записей, когда это необходимо, чтобы избежать перезаписи существующих записей с другими версиями), и он использует обработчик событий activate для удаления ранее кэшированные записи, которые больше не указаны в манифесте предварительного кеширования.

Если skipWaiting истинно, то обработчик activate, отвечающий за очистку устаревших URL-адресов из кеша, будет выполняться сразу после установки обновленного сервис-воркера.

В таких обстоятельствах есть ли причина не просто установить skipWaiting в значение true?

Использование skipWaiting сопряжено с небольшими рисками и из соображений безопасности мы отключили его по умолчанию в Workbox. (Он был включен по умолчанию в старых, sw-precache -генерированных сервис-воркерах.)

Предположим, что ваш HTML-код загружается в первую очередь в кеш (как правило, это лучшая практика), а затем через некоторое время после этой загрузки обнаруживается обновление сервис-воркера.

Риск 1: отложенная загрузка содержимого с отпечатками пальцев

Современные веб-приложения часто сочетают в себе два метода: асинхронную отложенную загрузку ресурсов только при необходимости (например, переключение на новое представление в одностраничном приложении) и добавление отпечатков пальцев (хэшей) для уникальной идентификации URL-адресов на основе содержимого, которое они содержат.

Традиционно либо сам HTML (или некоторый JavaScript, содержащий информацию о маршруте, которая также загружается на ранней стадии жизненного цикла страницы), содержит ссылку на текущий список URL-адресов, которые необходимо загружать с отложенной загрузкой.

Предположим, что версия вашего веб-приложения, которая была изначально загружена (до того, как произошло обновление Service worker), считает, что URL /view-one.abcd1234.js необходимо загрузить, чтобы отобразить /view-one. Но тем временем вы развернули обновление для своего кода, и /view-one.abcd1234.js был заменен на вашем сервере и в вашем манифесте предварительного кеширования на /view-one.7890abcd.js.

Если skipWaiting истинно, то /view-one.abcd1234.js будет очищено из кешей как часть события activate. Скорее всего, вы уже удалили его со своего сервера в рамках развертывания. Так что этот запрос не удастся.

Если skipWaiting ложно, то /view-one.abcd1234.js будет оставаться доступным в ваших кэшах до тех пор, пока все открытые клиенты сервис-воркера не будут закрыты. Обычно это то, что вам нужно.

Примечание. Хотя использование сервис-воркера может повысить вероятность столкновения с этим классом проблем, это проблема для всех веб-приложений, которые лениво загружают URL-адреса с поддержкой версий. У вас всегда должна быть предусмотрена обработка ошибок, чтобы обнаруживать сбои при отложенной загрузке и пытаться исправить, например, принудительно перезагрузив страницу. Если у вас есть такая логика восстановления и вас устраивает этот UX, вы все равно можете включить skipWaiting.

Риск 2: отложенная загрузка несовместимой логики

Это похоже на первый риск, но применяется, когда в ваших URL-адресах нет хеш-отпечатков. Если вы развернете обновление для своего HTML и соответствующее обновление для одного из ваших представлений, существующие клиенты могут прекратить отложенную загрузку версии /view-one.js, которая не соответствует структуре HTML, полученной из кеша.

Если skipWaiting ложно, то это вряд ли произойдет, поскольку /view-one.js, загруженный из кеша, должен соответствовать структуре HTML, загруженной из того же кеша. Вот почему это более безопасный вариант по умолчанию.

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

так что же делает clientsClaim?

clientsClaim гарантирует, что все неконтролируемые клиенты (то есть страницы), находящиеся в области действия, будут контролироваться сервисным воркером сразу после его активации. Если вы не включите его, они не будут контролироваться до следующей навигации.

Обычно это безопаснее, чем skipWaiting, и может быть полезно, если вы хотите, чтобы сервисный работник начал заполнять кеши времени выполнения раньше, чем позже.

Я отсылаю вас к разделу в Документ о жизненном цикле Service Worker для получения дополнительной информации.

person Jeff Posnick    schedule 06.08.2018
comment
Я не думаю, что ваш первый риск 1 верен на 100%. Когда новый код сервис-воркера и изменение файла view-one загружаются на сервер, событие install / activate не вызывается автоматически, поэтому, если пользователь нажимает на ссылку view-one, он все равно будет видеть старую / view- one.abcd1234.js, так как он еще не удален из кеша. Service worker обновляется, если браузер обновляет страницу. Ваш риск возникает, когда открыты 2 вкладки и при обновлении кода view-one и service worker на сервере пользователь обновляет одну вкладку. Теперь, если пользователь нажимает на этот маршрут в первой вкладке, это ошибка. имеет смысл? - person Giorgi Lagidze; 04.02.2020
comment
Риск 1 может возникнуть с одной вкладкой, когда вы обслуживаете предварительно кэшированный HTML и подресурсы с отложенной загрузкой и вызываете skipWaiting(). Старый предварительно кэшированный HTML-код будет использоваться для выполнения навигации до установки нового ПО, а затем, когда новое ПО будет установлено, использование skipWaiting() означает, что старый HTML-код будет ссылаться на хешированные подресурсы, которые больше не предварительно кэшируются. Я более подробно расскажу об этом на pawll.glitch.me. - person Jeff Posnick; 11.02.2020
comment
Я думаю, что путаница возникает, когда вы говорите, что SW обновляется, если браузер обновляет страницу, но это неправда. Проверка обновления ПО является асинхронной и запускается во время навигации, но к моменту завершения проверки и обнаружения нового ПО запрос навигации уже может быть выполнен с использованием ранее кэшированного HTML. Обновление ПО может происходить сразу после любой навигации. - person Jeff Posnick; 11.02.2020
comment
Итак, @JeffPosnick Вопрос 1) под навигацией вы имеете в виду, что выполняете navigator.serviceWorker.register ('/ sw.js'). Затем - каждый раз, когда пользователь переходит на другой маршрут или ссылку моего сайта, верно? Вопрос 2) поскольку у вас большой опыт в этом, считаете ли вы, что skipWaiting рискованно только в том случае, если приложение является SPA? и есть ли еще проблемы, которые skipWaiting может создать для меня, кроме этих 2 рисков, которые вы объяснили в этом ответе? Вопрос 3) Итак, вы предлагаете поместить вызов регистрации в какой-то слушатель, когда маршрут меняется для SPA, верно? - person Nika Kurashvili; 12.02.2020
comment
Вопрос 4). redfin.engineering/ Если вы посмотрите на первый подход, который он использует, я думаю, что он ошибается. v1 не будет пытаться загружать стили из сети, так как они уже находятся в кеше, помещенном v2. ты не согласен? - person Nika Kurashvili; 12.02.2020
comment
Пожалуйста, загляните на stackoverflow.com/a/51775987/385997, чтобы узнать, когда произойдут обновления. - person Jeff Posnick; 12.02.2020
comment
Я предполагаю, что если ресурсы все еще находятся на сервере, то риск 1 не является риском (потому что недавно установленный сервисный работник просто пойдет в сеть, чтобы получить его)? - person JoeTidee; 17.07.2020