必须在 Service Worker 的 install 阶段用 cache.addAll() 预缓存 CSS,否则离线时白屏;因为 CSS 是渲染阻塞资源,HTML 解析时同步请求,fetch 事件拦截已太晚,首次离线必失败。

必须在 Service Worker 的 install 阶段用 cache.addAll() 预缓存 CSS,否则离线时白屏不是“缓存没生效”,而是根本没机会加载——CSS 是渲染阻塞资源,HTML 解析到 <link rel="stylesheet"> 就会同步卡住,等不到 fetch 事件触发。
为什么不能靠 fetch 事件按需缓存 CSS
CSS 请求发生在 HTML 解析阶段,而 fetch 事件是在请求发起后才被 Service Worker 拦截。此时若已断网且 CSS 未预存,浏览器收不到任何响应,直接放弃样式应用,页面无样式渲染(白屏或布局错乱)。这不是缓存逻辑写错了,是时机彻底晚了。
-
fetch事件适合缓存图片、API 响应等非阻塞资源 - 对
event.request.destination === 'style'做判断再缓存,只能保后续刷新,救不了首次离线 - 即使你在
fetch里写了caches.match(...).then(r => r || fetch(...)),第一次断网仍失败
预缓存 CSS 的实操要点
cache.addAll() 看似简单,但路径、命名、版本三个环节一错全崩。它不报错,只静默跳过失败项,DevTools 里 Cache Storage 空空如也却找不到原因。
- 路径必须是绝对路径,和 HTML 中
<link href="/css/main.css">完全一致;css/main.css或./css/main.css都不会命中 - 构建工具(Vite/Webpack)生成的哈希文件名(如
main.a1b2c3.css)必须填进缓存列表,源码名无效 - 带查询参数的 URL(如
styles.css?v=2.1)会被视为独立缓存键,后续请求必须含相同参数才能匹配;推荐改CACHE_NAME替代加参数 -
cache.addAll()是原子操作:任一 URL 失败,整个 install 就失败,Service Worker 不会激活
确保 CSS 能被真正用上的拦截链
缓存了 ≠ 能用上。Service Worker 必须在运行时把 CSS 请求导向缓存,且不能漏掉 HTML 自身。
立即学习“前端免费学习笔记(深入)”;
-
index.html本身也必须被cache.addAll()预缓存,否则连 HTML 都打不开,CSS 根本不会被请求 -
fetch事件中要显式响应 CSS 请求:if (event.request.destination === 'style') { event.respondWith(caches.match(event.request)); } - 本地测试必须走 HTTP 协议(如
python3 -m http.server),file://下 Service Worker 直接禁用,这是浏览器硬性限制
最常被忽略的是构建产物路径与缓存列表的映射一致性——开发时看着是 styles.css,打包后可能是 assets/index.7f8a2d.css,而开发者还在缓存列表里写旧名字。这种错位不会报错,只会让离线体验在用户手里彻底失效。


















