必须在install阶段用cache.addAll()预缓存CSS,否则离线时HTML解析阻塞于导致白屏;因CSS是渲染阻塞资源,需同步加载,fetch事件中缓存已失效,且cache.addAll()为原子操作,路径须绝对一致并配合destination==='style'拦截响应。

必须在 install 阶段用 cache.addAll() 预缓存 CSS,否则离线时 HTML 解析卡在 就会白屏——这不是缓存逻辑写错了,是根本没让它提前就位。
为什么 install 阶段缓存 CSS 是硬性要求
CSS 是渲染阻塞资源:浏览器解析 HTML 到 时,会同步发起请求并等待响应完成,才继续构建 DOM 和渲染。此时若断网,且 Service Worker 还没把 styles.css 存进缓存,请求直接失败,页面空白或样式断裂。
fetch 事件中再缓存(比如 caches.match(event.request))对 CSS 来说太晚了,属于“亡羊补牢”。
-
cache.addAll()是原子操作:列表里任一 URL 失败,整个 install 就失败,不会留下半缓存状态 - 哪怕只改了一行 CSS,也必须更新
CACHE_NAME,否则旧缓存永不淘汰 - HTML 中的
和cache.addAll()里的路径必须完全一致——不能少前导斜杠,不能加./,也不能用相对路径
cache.addAll() 中 CSS 路径写错的典型表现
控制台不报错,但 DevTools → Application → Cache Storage 里就是找不到文件——这是静默失败的常态。
- 构建后路径被重命名(如 Webpack 输出
app.a1b2c3.css),缓存列表里必须填最终产物名,不是源文件名app.css - 带查询参数的 URL(如
app.css?v=2.1)会被当作独立缓存键,后续请求必须含相同参数才能命中;不推荐,改CACHE_NAME更可靠 - 如果 HTML 引用的是
/assets/main.css,cache.addAll(['assets/main.css'])会失败,必须写成['/assets/main.css']
fetch 事件中必须拦截并返回 CSS 缓存
install 阶段缓存只是“存进去”,不等于“能用上”。Service Worker 还得在运行时把对 CSS 的请求真正导向缓存,否则即使缓存存在,浏览器仍会尝试发网络请求并失败。
- 必须加类型过滤:
if (event.request.destination === 'style')再走缓存逻辑,避免误伤其他请求 - 必须调用
event.respondWith(),否则请求不被拦截,仍走网络 - 兜底逻辑要保留:
caches.match(event.request).then(r => r || fetch(event.request)),否则开发阶段热更新会失效 -
index.html本身也必须被cache.addAll()缓存,否则连 HTML 都打不开,CSS 根本没机会被请求
开发调试时最容易忽略的三个前提
90% 的“缓存无效”问题其实卡在启动方式或环境配置上。
-
file://协议下 Service Worker 完全不工作,这是浏览器强制限制——必须用http://localhost或 HTTPS - 注册时未指定
scope,而sw.js放在/js/sw.js,导致它只能拦截/js/下的请求,收不到对/css/app.css的 fetch - DevTools 中没勾选 “Update on reload” 和 “Offline”,导致你以为在离线测试,其实还在走网络
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











