必须在 activate 阶段清理旧缓存,因为此时旧 service worker 已退出控制权,新 sw 才能安全删除非当前版本缓存,避免资源错乱或白屏;标准做法是用 caches.keys() 获取所有缓存名,排除当前 cache_name 后逐个删除,并用 event.waituntil() 包裹。

监听 activate 事件清理旧缓存,是 Service Worker 保证缓存版本一致、避免离线资源错乱的关键一步。不清理旧缓存,新版本 SW 就会和过期资源共存,导致页面加载异常或白屏。
为什么必须在 activate 阶段清理?
install 完成后,新 SW 进入 waiting 状态;只有当所有已打开的页面关闭(或刷新)后,它才进入 activate 阶段。这时旧 SW 已完全退出控制权,新 SW 才能安全删除旧缓存——早了会删正在用的缓存,晚了旧缓存就一直占位。
标准写法:遍历并删除非当前版本缓存
核心逻辑是:获取所有缓存名 → 排除当前版本 → 删除其余缓存。
- 定义唯一缓存名(如
CACHE_NAME = 'my-app-static-v2'),确保每次更新都改名 - 在
activate事件中调用caches.keys()获取全部缓存名列表 - 用
cacheName !== CACHE_NAME筛出旧缓存,逐个执行caches.delete() - 用
event.waitUntil()包裹整个清理过程,防止 SW 在清理完成前被终止
常见错误要避开
以下操作看似省事,实则埋雷:
- 直接写
caches.delete('old-cache'):硬编码名字难维护,容易漏删或误删 - 用
self.skipWaiting()强制立即激活:新 SW 会接管仍在运行的旧页面,JS 和缓存版本可能不匹配,引发脚本错误或样式丢失 - 在 install 里删缓存:此时旧 SW 可能还在服务请求,强行删除会导致请求失败
- 完全不清理:旧缓存永久残留,占用空间且干扰新逻辑
附:最小可用 activate 示例
(注意:CACHE_NAME 必须随每次更新变更)
const CACHE_NAME = 'my-site-cache-v2';<br>self.addEventListener('activate', event => {<br> event.waitUntil(<br> caches.keys().then(cacheNames => {<br> return Promise.all(<br> cacheNames.map(name => {<br> if (name !== CACHE_NAME) {<br> return caches.delete(name);<br> }<br> })<br> )<br> });<br> });<br>});前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











