HTML5 离线缓存完全指南:Service Worker 与 PWA 离线体验
Introduction
HTML5 离线缓存技术让 Web 应用在断网状态下依然可以访问,是 PWA(Progressive Web App)的核心技术之一。离线能力的实现经历了 AppCache(已废弃)到 Service Worker 的演进。Service Worker 是一个独立于页面的后台脚本,可以拦截网络请求、缓存资源、推送通知,是现代 Web 应用必备的能力。
Service Worker 基本概念
/* Service Worker 生命周期:
1. Register(注册)→ 2. Install(安装)→ 3. Activate(激活)*/
/* 1. 在主页面注册 Service Worker */
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(reg => console.log('SW registered'))
.catch(err => console.error('SW failed:', err));
}
/* 2. sw.js - Install 事件:缓存静态资源 */
const CACHE_NAME = 'v1-static';
const ASSETS = ['/', '/index.html', '/style.css', '/app.js'];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(ASSETS))
.then(() => self.skipWaiting())
);
});
缓存策略与 Fetch 拦截
/* 3. sw.js - Fetch 拦截 */
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(cached => {
if (cached) return cached;
return fetch(event.request)
.then(response => {
if (response.ok) {
const clone = response.clone();
caches.open(CACHE_NAME)
.then(c => c.put(event.request, clone));
}
return response;
})
.catch(() => caches.match('/offline.html'));
})
);
});
/* 4. sw.js - Activate:清理旧缓存 */
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(keys =>
Promise.all(keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k)))
)
);
});
常见缓存策略
/* Cache First(缓存优先):静态资源 */
async function cacheFirst(request) {
const cached = await caches.match(request);
if (cached) return cached;
const response = await fetch(request);
return response;
}
/* Network First(网络优先):API 数据 */
async function networkFirst(request) {
try {
return await fetch(request);
} catch {
return await caches.match(request);
}
}
/* Stale-While-Revalidate:性能最佳 */
async function staleWhileRevalidate(request) {
const cached = caches.match(request);
const network = fetch(request).then(r => {
caches.open(CACHE_NAME).then(c => c.put(request, r.clone()));
return r;
});
return cached || network;
}
PWA 清单
/* manifest.json - 让网站可安装 */
{
"name": "绍大技术网",
"short_name": "Shaoda",
"start_url": "/",
"display": "standalone",
"background_color": "#faf8f5",
"theme_color": "#8b4513"
}
/* 注意:HTTPS 是 Service Worker 的硬性要求 */
常见问题
- AppCache 为什么废弃:规则复杂,容易缓存意外内容。Service Worker 提供了完整的编程能力,是替代方案。
- Service Worker 调试:Chrome DevTools → Application → Service Workers。
- 更新:新 sw.js install 完成后需要等所有页面关闭才激活(除非 skipWaiting)。
- MDN Service Worker:MDN Service Worker API
- Workbox:Google 的 Service Worker 工具库