离线功能详解
深入了解PWA离线支持的技术实现
Service Worker 工作原理
Service Worker 是运行在浏览器后台的脚本,独立于网页主线程,能够拦截网络请求、管理缓存,并提供离线功能支持。
核心特性
-
网络代理:拦截所有网络请求
-
缓存管理:智能缓存策略
-
后台同步:离线数据同步
-
推送通知:后台消息处理
生命周期
1
注册 (Register)
2
安装 (Install)
3
激活 (Activate)
4
运行 (Fetch)
缓存策略
Cache First
优先从缓存获取资源,适用于静态资源
// 缓存优先策略
if (cache.has(request)) {
return cache.match(request);
} else {
return fetch(request);
}
Network First
优先从网络获取,失败时使用缓存
// 网络优先策略
try {
const response = await fetch(request);
return response;
} catch {
return cache.match(request);
}
Stale While Revalidate
返回缓存,同时更新缓存
// 后台更新策略
const cachedResponse = cache.match(request);
const fetchPromise = fetch(request);
return cachedResponse || fetchPromise;
Cache Only
仅使用缓存,适用于离线模式
// 仅缓存策略
return cache.match(request) ||
new Response('离线内容不可用');
Service Worker 代码示例
1. 注册 Service Worker
// 在主线程中注册
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(registration => {
console.log('SW 注册成功:', registration.scope);
})
.catch(error => {
console.log('SW 注册失败:', error);
});
}
2. 安装事件处理
// service-worker.js
const CACHE_NAME = 'pwa-cache-v1';
const urlsToCache = [
'/',
'/styles.css',
'/script.js',
'/offline.html'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(urlsToCache))
);
});
3. 拦截网络请求
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
// 缓存命中,返回缓存
if (response) {
return response;
}
// 缓存未命中,发起网络请求
return fetch(event.request);
})
);
});
离线体验优化
预缓存关键资源
在安装时缓存核心文件,确保离线可用
优雅降级
提供离线页面,告知用户当前状态
后台同步
网络恢复时自动同步离线数据
页面导航测试
测试三级页面的导航功能:
当前导航状态
当前页面:
历史长度:
来源页面: