实现离线优先的关键是用 service worker 主动接管请求、预存资源、智能分流;需通过 https 注册并指定 scope 为 '/',install 阶段用 event.waituntil 缓存核心资源,fetch 阶段按类型应用 cache first 等策略,activate 阶段清理旧缓存并调用 clients.claim()。

实现离线优先(Offline-First)的关键不是配置浏览器默认缓存,而是用 Service Worker 主动接管请求、预存资源、智能分流——它绕过传统 HTTP 缓存机制,提供可编程的、更可靠的离线能力。
注册 Service Worker 并确保作用域正确
必须通过 HTTPS(localhost 除外)在页面加载完成后注册,且脚本建议放在根目录,保证最大拦截范围:
- 在 main.js 或 HTML 的 <script></script> 中注册:
if ('serviceWorker' in navigator) {<br> window.addEventListener('load', () =><br> navigator.serviceWorker.register('/sw.js')<br> .then(r => console.log('SW ready:', r.scope))<br> );<br>} - 注册时显式指定 scope: '/' 可避免子目录限制:
navigator.serviceWorker.register('/sw.js', { scope: '/' }) - 若 sw.js 放在
/assets/sw.js,则默认只控制/assets/下的请求,可能漏掉根路径 HTML
install 阶段预缓存核心骨架资源
首次访问时把关键静态文件存进 Cache Storage,确保断网也能渲染主界面:
- 定义带版本号的缓存名,如
'offline-cache-v2',便于后续更新识别 - 缓存列表应精简可靠,包含:
['/', '/index.html', '/app.js', '/style.css', '/icons/icon-192.png'] - 使用
event.waitUntil()确保缓存完成再进入激活态,失败会中断安装 - 调用
self.skipWaiting()让新 SW 立即激活,不等待旧版释放控制权
fetch 阶段按资源类型应用不同策略
每次网络请求触发 fetch 事件,根据资源性质决定响应来源:
-
HTML 和静态资源(CSS/JS/图标)用 Cache First:
先查缓存,命中直接返回;未命中再发网络请求,并可选存入缓存 -
API 数据建议用 Stale-while-revalidate:
立即返回缓存数据防白屏,后台拉新数据并更新缓存,兼顾体验与新鲜度 -
图片等大资源可用 Network Falling Back to Cache:
优先加载最新图,失败时展示已缓存版本,避免空缺 - 注意:fetch 响应流只能读一次,需用
response.clone()分别用于缓存和返回
activate 阶段清理旧缓存并接管页面
新 SW 激活时需主动管理缓存生命周期,防止冗余堆积和 stale 数据:
- 遍历
caches.keys(),删除所有不等于当前CACHE_NAME的缓存名 - 调用
self.clients.claim()让新 SW 立即控制当前已打开的页面(尤其对已加载但未被旧 SW 控制的页有效) - 配合 manifest.json 设置
display: 'standalone'和图标,完成 PWA 安装与启动体验
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











