То, что я пытаюсь достичь:
-
показать страницу с загрузчиком /spinner
-
если
service-worker.js
зарегистрирован и активен, затем проверьте наличие обновлений- , если нет обновлений, а затем удалить загрузчик
- если
updatefound
и установлена новая версия, затем перезагрузите страницу
- else register
service-worker.js
- когда
updatefound
, что означает, что новый был установлен, удалить загрузчик
- когда
Я использую модуль sw-precache
для генерации service-worker.js
и следующего регистрационного кода:
window.addEventListener('load', function() {
// show loader
addLoader();
navigator.serviceWorker.register('service-worker.js')
.then(function(swRegistration) {
// react to changes in `service-worker.js`
swRegistration.onupdatefound = function() {
var installingWorker = swRegistration.installing;
installingWorker.onstatechange = function() {
if(installingWorker.state === 'installed' && navigator.serviceWorker.controller){
// updated content installed
window.location.reload();
} else if (installingWorker.state === 'installed'){
// new sw registered and content cached
removeLoader();
}
};
}
if(swRegistration.active){
// here I know that `service-worker.js` was already installed
// but not sure it there are changes
// If there are no changes it is the last thing I can check
// AFAIK no events are fired afterwards
}
})
.catch(function(e) {
console.error('Error during service worker registration:', e);
});
});
После прочтения spec ясно, что обработчиков нет, например, updatenotfound
. Похоже, что serviceWorker.register
проверяет, изменилось ли service-worker.js
внутренне, запустив get-newest-worker-algorithm, но я не вижу похожих методов, открытых через public api.
Я думаю, что мои варианты:
- подождите пару секунд после того, как регистрация рабочего рабочего активируется, чтобы узнать, запущен ли
onupdatefound
-
выполнить пожарные пользовательские события из кодаservice-worker.js
, если кеш не был обновлен
Любые другие предложения?
Edit:
Я придумал код, который решает эту проблему, используя postMessage()
между регистрацией SW и клиентом SW (как предлагалось @pate)
После демонстрации пытается выполнить проверки через postMessage
между клиентом SW и регистрацией SW, но не работает, поскольку код SW уже кэшируется DEMO
Edit:
Итак, похоже, что я не могу реализовать то, что хочу, потому что:
- Когда рабочий сервисный активен, вы не можете проверять наличие обновлений, оценивая некоторый код в SW - это все тот же кешированный SW, никаких изменений там
- вам нужно подождать
onupdatefound
, больше ничего не будет уведомлять об изменениях в SW -
activation
старшего ПО передonupdatefound
- Если нет изменений, ничего не срабатывает после
activation
- Регистрация SW
update()
незрелая, продолжает меняться,Starting with Chrome 46, update() returns a promise that resolves with 'undefined' if the operation completed successfully or there was no update
- Установка таймаута для отложенного рендеринга представления является субоптимальной, поскольку нет четкого ответа на то, как долго он должен быть установлен, и зависит от размера SW.