Service Worker缓存策略与离线存储实践概述Service Worker作为现代Web应用的核心技术之一,为开发者提供了强大的网络拦截和缓存控制能力。通过合理配置缓存策略,可以显著提升应用的加载速度和离线使用体验。核心概念Service Worker生命周期Service Worker的生命周期包含以下几个关键阶段:注册阶段:浏览器下载并解析Service Worker脚本安装阶段:触发install事件,进行资源预缓存激活阶段:触发activate事件,清理旧缓存运行阶段:拦截网络请求,实现缓存策略缓存策略类型1. 缓存优先策略 (Cache First)self.addEventListener('fetch', (event) => {

event.respondWith(

caches.match(event.request)

.then((response) => {

return response || fetch(event.request);

})

);

});

2. 网络优先策略 (Network First)self.addEventListener('fetch', (event) => {

event.respondWith(

fetch(event.request)

.catch(() => {

return caches.match(event.request);

})

);

});

3. 缓存更新策略 (Cache with Network Update)self.addEventListener('fetch', (event) => {

event.respondWith(

caches.open(CACHE_NAME)

.then((cache) => {

return cache.match(event.request)

.then((response) => {

const fetchPromise = fetch(event.request).then((networkResponse) => {

cache.put(event.request, networkResponse.clone());

return networkResponse;

});

return response || fetchPromise;

});

})

);

});

实践应用基础配置const CACHE_NAME = 'v1';

const urlsToCache = [

'/',

'/styles/main.css',

'/script/main.js',

'/offline.html'

];

// 安装事件

self.addEventListener('install', (event) => {

event.waitUntil(

caches.open(CACHE_NAME)

.then((cache) => {

return cache.addAll(urlsToCache);

})

);

});

// 激活事件

self.addEventListener('activate', (event) => {

event.waitUntil(

caches.keys().then((cacheNames) => {

return Promise.all(

cacheNames.map((cacheName) => {

if (cacheName !== CACHE_NAME) {

return caches.delete(cacheName);

}

})

);

})

);

});

智能缓存策略// 根据资源类型选择不同策略

self.addEventListener('fetch', (event) => {

const { request } = event;

const url = new URL(request.url);

// API请求使用网络优先

if (url.pathname.startsWith('/api/')) {

event.respondWith(networkFirstStrategy(request));

}

// 静态资源使用缓存优先

else if (request.destination === 'image' ||

request.destination === 'style' ||

request.destination === 'script') {

event.respondWith(cacheFirstStrategy(request));

}

// 其他请求使用混合策略

else {

event.respondWith(staleWhileRevalidateStrategy(request));

}

});

// 网络优先策略

async function networkFirstStrategy(request) {

try {

const networkResponse = await fetch(request);

if (networkResponse.ok) {

const cache = await caches.open(CACHE_NAME);

cache.put(request, networkResponse.clone());

}

return networkResponse;

} catch (error) {

const cachedResponse = await caches.match(request);

return cachedResponse || new Response('网络错误', { status: 408 });

}

}

// 缓存优先策略

async function cacheFirstStrategy(request) {

const cachedResponse = await caches.match(request);

if (cachedResponse) {

return cachedResponse;

}

try {

const networkResponse = await fetch(request);

if (networkResponse.ok) {

const cache = await caches.open(CACHE_NAME);

cache.put(request, networkResponse.clone());

}

return networkResponse;

} catch (error) {

return new Response('资源不可用', { status: 503 });

}

}

// 缓存更新策略

async function staleWhileRevalidateStrategy(request) {

const cache = await caches.open(CACHE_NAME);

const cachedResponse = await cache.match(request);

const fetchPromise = fetch(request).then((networkResponse) => {

if (networkResponse.ok) {

cache.put(request, networkResponse.clone());

}

return networkResponse;

});

return cachedResponse || fetchPromise;

}

缓存版本管理// 版本控制

const VERSION = 'v2.0.0';

const CACHE_PREFIX = 'my-app-';

const CACHE_NAME = `${CACHE_PREFIX}${VERSION}`;

// 清理旧版本缓存

self.addEventListener('activate', (event) => {

event.waitUntil(

caches.keys().then((cacheNames) => {

return Promise.all(

cacheNames.map((cacheName) => {

if (cacheName.startsWith(CACHE_PREFIX) && cacheName !== CACHE_NAME) {

return caches.delete(cacheName);

}

})

);

})

);

});

性能优化缓存大小控制const MAX_CACHE_SIZE = 50; // MB

async function trimCache(cacheName, maxItems) {

const cache = await caches.open(cacheName);

const requests = await cache.keys();

if (requests.length > maxItems) {

const requestsToDelete = requests.slice(0, requests.length - maxItems);

await Promise.all(requestsToDelete.map((request) => cache.delete(request)));

}

}

智能预缓存// 根据用户行为预缓存

self.addEventListener('message', (event) => {

if (event.data.type === 'PRECACHE_URLS') {

const urlsToPrecache = event.data.urls;

event.waitUntil(

caches.open(CACHE_NAME)

.then((cache) => {

return cache.addAll(urlsToPrecache);

})

);

}

});

错误处理离线页面处理self.addEventListener('fetch', (event) => {

event.respondWith(

fetch(event.request)

.catch(() => {

return caches.match('/offline.html');

})

);

});

网络超时处理function fetchWithTimeout(request, timeout = 5000) {

return Promise.race([

fetch(request),

new Promise((_, reject) =>

setTimeout(() => reject(new Error('Request timeout')), timeout)

)

]);

}

最佳实践1. 渐进式增强始终确保Service Worker是渐进式增强,不影响基本功能。

2. 缓存策略选择静态资源:缓存优先API请求:网络优先关键资源:缓存更新非关键资源:网络优先3. 版本管理使用语义化版本控制,确保缓存更新的可控性。

4. 错误处理完善的错误处理机制,确保离线体验的一致性。

5. 性能监控监控缓存命中率和网络性能,持续优化策略。总结Service Worker缓存策略是构建现代Web应用的重要组成部分。通过合理选择和配置缓存策略,可以显著提升应用的性能和用户体验。在实际应用中,需要根据具体的业务需求和资源特性,选择最适合的缓存策略组合。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部