Service Worker缓存策略更新后页面还是加载旧资源怎么办?
最近给项目加了Service Worker做静态资源缓存,但今天部署新版本后发现用户还是在加载旧资源。我尝试过清除浏览器缓存和用cache-first策略,但页面内容就是不更新,这是什么情况啊?
我设置的策略是先查缓存再请求网络,代码大概是这样写的:
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
.then(cacheRes => cacheRes || fetch(event.request))
);
});
后来试过在sw.js里加版本号,用caches.open('v1'),但用户升级到v2版本后旧缓存还是没清理掉。难道Service Worker本身没被重新注册吗?刷新页面的时候控制台也没有报错提示啊…
先说一下正确的做法。你需要监听
install和activate事件,在activate阶段清理旧缓存。下面是一个完整的代码示例:有几个点需要注意。首先,Service Worker文件本身必须发生变化才能触发更新,所以你加版本号是对的,但记得确保文件内容确实有改动,比如修改注释或者变量名。其次,
activate阶段是清理旧缓存的最佳时机,而不是在install阶段做这件事,因为这时旧的Service Worker可能还在运行。最后吐槽一句,调试Service Worker真的挺烦的,尤其是缓存问题,建议在开发阶段把Chrome DevTools的“Update on reload”选项打开,这样每次刷新都会强制更新Service Worker,省得抓狂。
如果还是有问题,检查一下是不是浏览器对Service Worker文件也做了强缓存,比如你的服务器配置了过长的
Cache-Control头,这种情况下需要调整服务器响应头,确保sw.js文件不会被缓存太久。### 问题核心
你已经尝试在
caches.open('v1')中使用版本号来控制缓存,但如果你没有在 Service Worker 更新时主动删除旧缓存,浏览器不会自动清理它们。也就是说,v1的缓存会一直存在,直到你手动清除或更新 SW 时没有处理旧缓存。### 解决方法
你需要做两件事:
1. **强制 Service Worker 更新**
2. **在激活阶段清除旧缓存**
### 示例代码
修改你的
sw.js文件,添加install和activate阶段处理逻辑:### 额外说明
- 确保你的 Service Worker 文件(sw.js)有更新内容,否则浏览器不会重新注册 SW。
- 建议每次部署新版本时都更新
CACHE_NAME。- 页面刷新不一定触发 SW 更新,只有当浏览器认为 SW 文件内容发生变化时才会触发。可以考虑在注册 SW 时加上时间戳避免缓存:
navigator.serviceWorker.register('/sw.js?_=时间戳')。这样改完之后,下次更新时应该不会再出现加载旧资源的问题了。