Взаимодействие с Service Worker¶
28.02.2022
Импорт ServiceWorkerModule
в ваш AppModule
не просто регистрирует Service Worker, он также предоставляет несколько сервисов, которые вы можете использовать для взаимодействия с сервисным работником и управления кэшированием вашего приложения.
Предварительные условия¶
Базовое понимание следующего:
Служба SwUpdate
¶
Служба SwUpdate
предоставляет вам доступ к событиям, которые указывают, когда работник службы обнаруживает и устанавливает доступное обновление для вашего приложения.
Служба SwUpdate
поддерживает три отдельные операции:
- Получить уведомление, когда обновленная версия обнаружена на сервере, установлена и готова к локальному использованию или когда установка не удалась.
- Попросить работника службы проверить сервер на наличие новых обновлений
- Попросите работника службы активировать последнюю версию приложения для текущей вкладки
Обновления версий¶
versionUpdates
является Observable
свойством SwUpdate
и испускает четыре типа событий:
Типы событий | Подробности |
---|---|
VersionDetectedEvent | Вызывается, когда Service Worker обнаружил новую версию приложения на сервере и собирается начать ее загрузку. |
NoNewVersionDetectedEvent | Выдается, когда работник службы проверил версию приложения на сервере и не обнаружил новой версии. |
VersionReadyEvent | Вызывается, когда новая версия приложения доступна для активации клиентами. Оно может быть использовано для уведомления пользователя о доступном обновлении или для того, чтобы попросить его обновить страницу. |
VersionInstallationFailedEvent | Вызывается, когда установка новой версии не удалась. Может использоваться для регистрации/мониторинга. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Проверка наличия обновлений¶
Можно попросить работника службы проверить, были ли развернуты обновления на сервере. Работник службы проверяет наличие обновлений во время инициализации и при каждом навигационном запросе — то есть, когда пользователь переходит с другого адреса на ваше приложение.
Однако вы можете вручную проверять наличие обновлений, если у вас сайт, который часто меняется, или если вы хотите, чтобы обновления происходили по расписанию.
Это можно сделать с помощью метода checkForUpdate()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
Этот метод возвращает Promise<boolean>
, который указывает, доступно ли обновление для активации. Проверка может закончиться неудачей, что приведет к отказу от Promise
.
Чтобы избежать негативного влияния на начальный рендеринг страницы, ServiceWorkerModule
по умолчанию ждет до 30 секунд, пока приложение стабилизируется, прежде чем зарегистрировать скрипт ServiceWorker. Постоянный опрос обновлений, например, с помощью setInterval() или interval() RxJS, не позволяет приложению стабилизироваться, и скрипт ServiceWorker не регистрируется в браузере до достижения верхнего предела в 30 секунд.
Это справедливо для любого вида опроса, выполняемого вашим приложением. Для получения дополнительной информации ознакомьтесь с документацией isStable.
Чтобы избежать этой задержки, сначала дождитесь стабилизации приложения, прежде чем начать опрашивать обновления, как показано в предыдущем примере. В качестве альтернативы вы можете определить другую стратегию регистрации для ServiceWorker.
Обновление до последней версии¶
Вы можете обновить существующую вкладку до последней версии, перезагрузив страницу, как только будет готова новая версия. Чтобы не прерывать работу пользователя, как правило, целесообразно запросить у него подтверждение, что он согласен перезагрузить страницу и обновить ее до последней версии:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Вызов SwUpdate#activateUpdate обновляет вкладку до последней версии без перезагрузки страницы, но это может нарушить работу приложения.
Обновление без перезагрузки может создать несоответствие версий между оболочкой приложения и другими ресурсами страницы, такими как куски с ленивой загрузкой, имена файлов которых могут меняться между версиями.
Вы должны использовать activateUpdate()
, только если вы уверены, что это безопасно для вашего конкретного случая использования.
Обработка невосстановимого состояния¶
В некоторых случаях версия приложения, используемая сервисным работником для обслуживания клиента, может находиться в поврежденном состоянии, которое невозможно восстановить без полной перезагрузки страницы.
Например, представьте следующий сценарий:
-
Пользователь открывает приложение в первый раз, и работник службы кэширует последнюю версию приложения.
Предположим, что кэшированные активы приложения включают
index.html
,main.<main-hash-1>.js
иlazy-chunk.<lazy-hash-1>.js
. -
Пользователь закрывает приложение и не открывает его некоторое время.
-
Через некоторое время новая версия приложения развертывается на сервере.
Эта новая версия включает файлы
index.html
,main.<main-hash-2>.js
иlazy-chunk.<lazy-hash-2>.js
.Хеши теперь другие, потому что содержимое файлов изменилось.
Старая версия больше не доступна на сервере.
-
Тем временем, браузер пользователя решил удалить
lazy-chunk.<lazy-hash-1>.js
из своего кэша.Браузеры могут решить удалить определенные (или все) ресурсы из кэша, чтобы освободить место на диске.
-
Пользователь снова открывает приложение.
Рабочий сервис обслуживает последнюю версию, известную ему на данный момент, а именно старую версию (
index.html
иmain.<main-hash-1>.js
). -
Позже приложение запрашивает ленивый пакет,
lazy-chunk.<lazy-hash-1>.js
. -
Service Worker не может найти актив в кэше (помните, что браузер изгнал его).
Он также не может получить его с сервера (потому что на сервере теперь есть только
lazy-chunk.<lazy-hash-2>.js
из более новой версии).
В предыдущем сценарии работник службы не может обслужить актив, который обычно кэшируется. Эта конкретная версия приложения сломана, и нет способа исправить состояние клиента без перезагрузки страницы. В таких случаях работник службы уведомляет клиента, отправляя событие UnrecoverableStateEvent
.
Подпишитесь на SwUpdate#unrecoverable
, чтобы получать уведомления и обрабатывать эти ошибки.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Больше о рабочих службах Angular¶
Вас также может заинтересовать следующее: