admin管理员组文章数量:1427333
Bellow is how I register my serviceworker :
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
function updateOnlineStatus() {
SnackBar.show({
text: navigator.onLine ? onlineMsg : offlineMsg,
backgroundColor: '#000000',
actionText: close,
actionTextColor: '#d2de2f',
customClass: 'custom-snackbar',
});
}
window.addEventListener('online', updateOnlineStatus);
window.addEventListener('offline', updateOnlineStatus);
navigator.serviceWorker.register('sw.js').then((reg) => {
reg.onupdatefound = () => {
const installingWorker = reg.installing;
installingWorker.onstatechange = () => {
switch (installingWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
SnackBar.show({
text: refreshMsg,
backgroundColor: '#000000',
actionText: refresh,
actionTextColor: '#d2de2f',
onActionClick: () => { location.reload(); },
customClass: 'custom-snackbar',
});
} else {
console.info(availableMsg);
}
break;
case 'redundant':
console.info(redundantMsg);
break;
default:
break;
}
};
};
}).catch((e) => {
console.error(errorMsg, e);
});
});
}
This service-worker is generated during build by Workbox.
I'm a bit worried because these notifications are displayed on my puter (ubuntu + chrome 59.0.3071.115
) however never on my mobile (android 6.0.1
+ chrome 59.0.3071.125
)
After analyzing with remote debugging feature, it looks like onupdatefound
is never triggered on my mobile.
I feel very bad about UX, thinking about visitors on mobile that wouldn't know that a new version of website is pending ...
Any suggestion or advice will be appreciated
Edit 1 : I've found more details on "Browser Compatibility" section of this webpage : . It looks like support of this feature by Chrome for Android is unknown.
Do you guys have a kind of fallback / workaround when browser do not support onupdatefound
event ?
Edit 2 : In response to Jeff,
sw.js
header is managed in .htaccess
file :
<Files sw.js>
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</Files>
which produces :
accept-ranges: bytes
cache-control: max-age=0, no-cache, no-store, must-revalidate
content-encoding: br
content-language: fr-FR
content-length: 1636
content-type: application/javascript; charset=utf-8
date: Fri, 21 Jul 2017 13:04:06 GMT
expires: Wed, 11 Jan 1984 05:00:00 GMT
last-modified: Tue, 18 Jul 2017 02:58:30 GMT
pragma: no-cache
Regarding workbox fine tuning you suggest, I didn't find time to dig in yet so i'm using the easy workbox-build
in a gulp file. But I hopefully will :)
// Service Worker generation
gulp.task('bundle-sw', gulp.series('generate-sitemap', () => {
return wbBuild.generateSW({
globDirectory: gulpOutputDir,
swDest: `${gulpOutputDir}/sw.js`,
globPatterns: ['**/*.{html,png,xml,css,ico,txt,json,svg,js,map,gif,jpeg,jpg,bmp,cur,webp,woff2}'],
skipWaiting: true,
clientsClaim: true,
})
.then(() => {
console.warn('Service worker generated.');
})
.catch((err) => {
console.error(`[ERROR] This happened: ${err}`);
});
}));
Do you think it could be caused by skipWaiting: true
?
Edit 3 : Trying with BroadcastChannel
navigator.serviceWorker.register('/sw.js').then((reg) => {
console.log('test');
const updateChannel = new BroadcastChannel('precache-updates');
updateChannel.addEventListener('message', event => {
console.log(`Cache updated: ${event.data.payload.updatedUrl}`);
});
}).catch((e) => {
console.error(errorMsg, e);
});
Even if test
is outputed in log on Chrome, mobile, or firefox, update messages are only thrown on Chrome
Bellow is how I register my serviceworker :
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
function updateOnlineStatus() {
SnackBar.show({
text: navigator.onLine ? onlineMsg : offlineMsg,
backgroundColor: '#000000',
actionText: close,
actionTextColor: '#d2de2f',
customClass: 'custom-snackbar',
});
}
window.addEventListener('online', updateOnlineStatus);
window.addEventListener('offline', updateOnlineStatus);
navigator.serviceWorker.register('sw.js').then((reg) => {
reg.onupdatefound = () => {
const installingWorker = reg.installing;
installingWorker.onstatechange = () => {
switch (installingWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
SnackBar.show({
text: refreshMsg,
backgroundColor: '#000000',
actionText: refresh,
actionTextColor: '#d2de2f',
onActionClick: () => { location.reload(); },
customClass: 'custom-snackbar',
});
} else {
console.info(availableMsg);
}
break;
case 'redundant':
console.info(redundantMsg);
break;
default:
break;
}
};
};
}).catch((e) => {
console.error(errorMsg, e);
});
});
}
This service-worker is generated during build by Workbox.
I'm a bit worried because these notifications are displayed on my puter (ubuntu + chrome 59.0.3071.115
) however never on my mobile (android 6.0.1
+ chrome 59.0.3071.125
)
After analyzing with remote debugging feature, it looks like onupdatefound
is never triggered on my mobile.
I feel very bad about UX, thinking about visitors on mobile that wouldn't know that a new version of website is pending ...
Any suggestion or advice will be appreciated
Edit 1 : I've found more details on "Browser Compatibility" section of this webpage : https://developer.mozilla/en-US/docs/Web/API/ServiceWorkerRegistration/onupdatefound. It looks like support of this feature by Chrome for Android is unknown.
Do you guys have a kind of fallback / workaround when browser do not support onupdatefound
event ?
Edit 2 : In response to Jeff,
sw.js
header is managed in .htaccess
file :
<Files sw.js>
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</Files>
which produces :
accept-ranges: bytes
cache-control: max-age=0, no-cache, no-store, must-revalidate
content-encoding: br
content-language: fr-FR
content-length: 1636
content-type: application/javascript; charset=utf-8
date: Fri, 21 Jul 2017 13:04:06 GMT
expires: Wed, 11 Jan 1984 05:00:00 GMT
last-modified: Tue, 18 Jul 2017 02:58:30 GMT
pragma: no-cache
Regarding workbox fine tuning you suggest, I didn't find time to dig in yet so i'm using the easy workbox-build
in a gulp file. But I hopefully will :)
// Service Worker generation
gulp.task('bundle-sw', gulp.series('generate-sitemap', () => {
return wbBuild.generateSW({
globDirectory: gulpOutputDir,
swDest: `${gulpOutputDir}/sw.js`,
globPatterns: ['**/*.{html,png,xml,css,ico,txt,json,svg,js,map,gif,jpeg,jpg,bmp,cur,webp,woff2}'],
skipWaiting: true,
clientsClaim: true,
})
.then(() => {
console.warn('Service worker generated.');
})
.catch((err) => {
console.error(`[ERROR] This happened: ${err}`);
});
}));
Do you think it could be caused by skipWaiting: true
?
Edit 3 : Trying with BroadcastChannel
navigator.serviceWorker.register('/sw.js').then((reg) => {
console.log('test');
const updateChannel = new BroadcastChannel('precache-updates');
updateChannel.addEventListener('message', event => {
console.log(`Cache updated: ${event.data.payload.updatedUrl}`);
});
}).catch((e) => {
console.error(errorMsg, e);
});
Even if test
is outputed in log on Chrome, mobile, or firefox, update messages are only thrown on Chrome
- developers.google./web/fundamentals/instant-and-offline/… u may want to revise your observer after reviewing the docs. – Robert Rowntree Commented Jul 19, 2017 at 23:13
2 Answers
Reset to default 2There shouldn't be any difference in the service worker implementation in Chrome on Android and Linux that would account for one platform not having the updatefound
event exposed on a service worker registration. (MDN isn't necessarily authoritative here.)
Whenever I've debugged this sort of unpredictable updates in the past, it's been due to interactions with the HTTP cache and the sw.js
script. Can you check to see what Cache-Control
headers you're using when you serve sw.js
?
Also, you mention that you're using Workbox—you have access to a more advanced approach to checking for updated resources if that's the case. The workbox-broadcast-cache-update
plugin (which is enabled by default if you're using workbox-sw
's precache()
method) can announce when a specific cached resource is updated, and then you can listen for that message on your page using the Broadcast Channel API. This allows you to only show your SnackBar
when the most important resources change—like the HTML—rather than less important resources, like random images that might be precached.
As you suspected, problem didn't e at all from Service Worker by itself.
I started from scratch and tried to identify the origin of this issue, adding code piece by piece until no more event is exposed. I figured it out : it was because of an "expensive" loop used in a three.js
animation.
After puting this piece of code in a worker, my page is now able to catch these events on mobile or Firefox and user's notification works just fine !
About the confusing fact that it was working on desktop version of Chrome, I guess it's because it must support multithreading ...
Thanks again for your help :)
本文标签: javascriptserviceworker onupdatefound not triggered on mobileStack Overflow
版权声明:本文标题:javascript - service-worker `onupdatefound` not triggered on mobile - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745493566a2660709.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论