必须在install阶段用cache.addAll()预缓存CSS,路径须与HTML中href完全一致(如/css/main.css),并在fetch事件中按destination==='style'拦截响应,配合CACHE_NAME版本更新与activate阶段清理旧缓存。

install 阶段必须用 cache.addAll() 预缓存 CSS
CSS 是渲染阻塞资源,HTML 解析到 时会同步等待响应。如果此时离线,且 Service Worker 还没把该文件存进缓存,请求直接失败——结果不是样式错乱,而是白屏或部分 DOM 不渲染。
常见静默失败现象:cache.addAll(['css/main.css']) 写了,但 DevTools → Application → Cache Storage 里压根找不到这个键;控制台无报错,因为路径不匹配就跳过,不抛异常。
- 路径必须和 HTML 中
href的值**完全一致**:写成/css/main.css才对,css/main.css或./css/main.css都无效 - 构建后若被哈希重命名(如
/css/main.a1b2c3.css),缓存列表里就得填最终产物路径,不是源码路径 - 带查询参数的 URL(如
/styles.css?v=2.1)会被当作独立缓存键,后续请求必须含相同参数才命中;推荐改CACHE_NAME控制更新,而非依赖 query
fetch 事件中必须按 destination === 'style' 拦截
只在 install 阶段存进去,不等于浏览器真会从缓存读取。Service Worker 必须在运行时显式拦截 CSS 请求,并用 event.respondWith() 返回缓存响应,否则仍走网络并失败。
- 不能只靠
caches.match(event.request)泛匹配,要加类型判断:if (event.request.destination === 'style')再执行缓存逻辑,避免误伤图片、脚本等其他请求 - 必须调用
event.respondWith(),否则拦截不生效,请求照常发往网络 - 兜底逻辑不可少:缓存未命中时,仍需
fetch(event.request)回退,否则开发阶段热更新会中断
CACHE_NAME 变更才是 CSS 缓存更新的唯一可靠方式
修改一行 CSS 后用户看不到效果?90% 是因为 CACHE_NAME 没变。Cache API 不会自动对比内容哈希,旧缓存永不淘汰,除非你主动换名字。
-
sw.js文件内容必须随版本变更(哪怕只加一行注释),浏览器才认为有新 Service Worker,才会触发install和activate - 每次发版后务必检查:
caches.open('shell-v2').keys()是否真返回了目标 CSS 路径 - 在
activate事件中清理旧缓存:caches.delete('shell-v1'),否则磁盘空间持续增长,且可能干扰新缓存命中
离线加载失败?先确认协议与环境是否合法
90% 的“CSS 缓存无效”问题,其实卡在启动方式上——file:// 协议下 Service Worker 根本不会激活,所有缓存逻辑形同虚设。
必须满足以下任一条件才能启用 SW:
- 通过 HTTPS 访问(生产环境)
- 本地开发时用
localhost(Chrome/Firefox 允许) - 或配置本地 SSL 服务(如 Vite 的
--https)
另外,index.html 本身也必须被 cache.addAll() 预缓存,否则连 HTML 都打不开,CSS 根本没机会被请求。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











