PWA服务工作者更新后,用户如何自动获取新版本而不手动刷新?
我在React项目里用了PWA,服务工作者注册没问题,但发现用户更新时得手动刷新才能看到新内容。我尝试在useEffect里检查更新:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js').then(reg => {
reg.addEventListener('updatefound', () => {
const newWorker = reg.installing;
newWorker.addEventListener('statechange', () => {
if (newWorker.state === 'activated') {
window.location.reload();
}
});
});
});
});
}
但这样会导致频繁刷新体验差,有没有更好的方式让用户在后台更新后,提示点击刷新按钮就能生效?感觉现在逻辑有问题,但查文档没找到具体解决方法。
建议改成提示用户有新版本,等用户点击再 reload。你监听到 updatefound 后,可以设置一个状态,前端显示一个提示按钮,让用户主动刷新。这样不会打断用户操作。
代码大致结构如下:
在 useEffect 里:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js').then(reg => {
reg.addEventListener('updatefound', () => {
const newWorker = reg.installing;
newWorker.addEventListener('statechange', () => {
if (newWorker.state === 'activated') {
// 这里发个通知,让前端弹个提示,比如 “发现新版本,点击刷新”
showUpdatePrompt();
}
});
});
});
});
}
function showUpdatePrompt() {
// 你可以用一个全局状态或事件通知前端弹提示框
// 比如用 Redux 或 eventBus 触发一个提示
}
用户点击确认后,再执行 window.location.reload(); 就可以了。
另外后端处理上要确保 sw.js 的版本更新,浏览器才会触发更新流程。可以加个版本号在文件名后面,比如 sw.js?v=1.0.1。
这样用户体验会好很多,不会突然刷新页面,也避免了缓存导致的问题。
这样用户有选择权,不会被强制刷新搞到崩溃。