必须在install阶段用cache.addAll()预缓存CSS,否则首次离线访问必然白屏或样式断裂;因CSS是渲染阻塞资源,HTML解析时同步等待其加载,断网且未提前缓存则请求失败、样式缺失。

必须在 install 阶段用 cache.addAll() 预缓存 CSS 文件,否则首次离线访问必然白屏或样式断裂——这不是缓存没写对,而是根本没让它“提前就位”。
为什么 install 阶段缓存 CSS 是硬性要求
CSS 是渲染阻塞资源:HTML 解析到 <link rel="stylesheet" href="styles.css"> 时,会同步发起请求并等待响应完成才继续渲染。如果此时断网,且 Service Worker 没在激活前就把 styles.css 存进缓存,这个请求就会失败,浏览器得不到任何 CSS 内容。
fetch 事件中按需缓存(比如 caches.match(event.request))只适用于非阻塞资源,对 CSS 来说太晚了。
-
install阶段的cache.addAll()是原子操作:所有 URL 必须全部成功,否则整个 install 失败,不会留下半缓存状态 - 即使你只改了一行 CSS,也必须更新
CACHE_NAME,否则旧缓存永不淘汰,用户永远看不到新样式
cache.addAll() 中 CSS 路径写错的典型表现
控制台不报错,但 DevTools → Application → Cache Storage 里就是找不到 styles.css——因为 cache.addAll() 对路径极其敏感,静默失败是常态。
立即学习“前端免费学习笔记(深入)”;
- 必须用绝对路径,和 HTML 中
<link href="">的值完全一致:比如 HTML 里是/css/main.css,就不能写成css/main.css或./css/main.css - 构建后路径可能变化:若用 Webpack/Vite 打包,CSS 被哈希重命名(如
main.a1b2c3.css),缓存列表里就得填最终产物名,不是源文件名 - 带查询参数的 URL(如
styles.css?v=2.1)会被当作独立键,后续请求必须含相同参数才能命中;不推荐,改CACHE_NAME更可靠
离线时 CSS 仍加载失败?检查这三个拦截点
缓存了 CSS 不等于它能被用上——Service Worker 还得在运行时把请求真正导向缓存。
-
fetch事件必须监听并响应 CSS 请求:event.respondWith(caches.match(event.request).then(r => r || fetch(event.request))) - 建议加类型过滤,避免误伤其他请求:
if (event.request.destination === 'style')再走缓存逻辑 -
index.html本身也必须被cache.addAll()缓存,否则连 HTML 都打不开,CSS 根本没机会被请求
开发阶段 CSS 缓存总不生效?先确认协议和环境
90% 的“缓存无效”问题其实卡在启动方式上——file:// 协议下 Service Worker 完全不工作,这是浏览器强制限制。
必须通过 http:// 或 https:// 提供服务(例如用 npx serve、vite preview、webpack-dev-server),且确保注册脚本运行在页面 load 后、作用域正确(通常为 /)。
另外注意:Service Worker 的缓存不会自动继承 HTTP 缓存头,也不受 Cache-Control: no-store 影响;但若服务器返回 304 或重定向,cache.addAll() 会失败——务必确保构建产物可直接 GET 返回 200。


















