秒开核心是service worker预缓存首屏资源并在fetch中智能返回。install阶段用cache.addall预存html、js、css等;fetch事件中优先响应缓存,未命中再网络请求并更新缓存;需配合http强缓存与版本化更新机制。

网页通过离线缓存实现秒开,核心在于让关键资源“提前就位”、请求“无需等待网络”。不是等用户点开才去加载,而是安装阶段就预存好 HTML、JS、CSS、图标等首屏必需文件;后续访问时,Service Worker 直接从本地缓存读取并响应,跳过网络往返,自然达到毫秒级加载。
用 Service Worker 预缓存首屏资源
这是实现秒开最直接有效的方式。在 Service Worker 的 install 阶段,把首页 HTML、主 JS/CSS、Logo、字体等静态资源列表写入缓存(如使用 cache.addAll())。这些资源一旦缓存成功,下次打开页面时,即使断网,也能立刻渲染出完整首屏。
- 缓存策略建议:只缓存变动极少的资源(如构建后带 hash 的文件),避免缓存失效问题
- HTML 文件需特殊处理:不能直接缓存原始 index.html(它常动态生成),可用“网络优先但降级为缓存”的策略,或配合构建工具生成可缓存的 shell HTML
- 示例关键代码:
self.addEventListener('install', e => {<br> e.waitUntil(caches.open('v1').then(cache => cache.addAll(['/index.html', '/main.a1b2c3.js', '/style.f4d5e6.css'])));<br>});
拦截请求并智能返回缓存
Service Worker 在 fetch 事件中接管所有网络请求。对导航请求(request.destination === 'document')和静态资源请求,可按规则返回缓存内容,而不是每次都发请求。
- 首屏导航请求:优先匹配缓存中的 HTML,命中则立即返回,不触发网络请求
- API 数据请求:可结合 Cache API + IndexedDB 缓存上一次响应,弱网时展示“上次数据”,提升感知速度
- 注意 fallback 逻辑:缓存未命中时再走网络,并在获取成功后更新缓存,形成闭环
搭配浏览器原生缓存协同生效
离线缓存不是孤立使用的。Service Worker 要和 HTTP 强缓存(Cache-Control: max-age=31536000)配合——静态资源本身带长期强缓存,Service Worker 安装时就能快速读取,减少 install 阶段等待;同时,CDN 返回的资源若已带正确缓存头,也能被 SW 自动纳入管理范围。
- 确保服务器为 JS/CSS/图片等资源配置了合理的
Cache-Control头(如 public, max-age=1年) - 避免在 HTML 响应头中设置强缓存(它不该被长期缓存),否则可能阻塞 SW 更新
- 开发时可通过 Chrome DevTools 的 Application → Cache Storage 查看实际缓存内容,确认资源是否写入
保证缓存更新及时且平滑
缓存旧了,秒开反而会展示错误内容。所以必须设计可靠的更新机制:
- 每次部署新版本时,修改 Service Worker 文件内容(哪怕加个注释),触发浏览器下载新脚本、进入 install 阶段
- 在 activate 阶段清理旧缓存(
caches.delete('v0')),防止磁盘占用膨胀 - 对用户无感:新 SW 安装后不会立即接管页面,要等所有旧页面关闭;可调用
skipWaiting()+clients.claim()实现立即激活(适合纯静态站点)











