推荐答案
Service Worker 的缓存策略是通过拦截网络请求并根据预定义的规则来决定如何处理这些请求。常见的缓存策略包括:
- Cache First:优先从缓存中获取资源,如果缓存中没有,则从网络请求。
- Network First:优先从网络请求资源,如果网络请求失败,则从缓存中获取。
- Stale-While-Revalidate:先从缓存中返回资源,同时发起网络请求更新缓存。
- Cache Only:只从缓存中获取资源,如果缓存中没有,则返回错误。
- Network Only:只从网络请求资源,不使用缓存。
这些策略可以通过 Service Worker 的 fetch 事件来实现,开发者可以根据具体需求选择合适的策略。
本题详细解读
Cache First
Cache First 策略适用于那些不经常变化的静态资源,如 CSS、JavaScript 文件等。当 Service Worker 拦截到请求时,首先检查缓存中是否存在该资源。如果存在,则直接从缓存中返回;如果不存在,则从网络请求资源并将其缓存起来。
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});Network First
Network First 策略适用于那些需要实时更新的资源,如 API 数据。当 Service Worker 拦截到请求时,首先尝试从网络获取资源。如果网络请求成功,则返回网络响应并更新缓存;如果网络请求失败,则从缓存中返回资源。
self.addEventListener('fetch', event => {
event.respondWith(
fetch(event.request).catch(() => {
return caches.match(event.request);
})
);
});Stale-While-Revalidate
Stale-While-Revalidate 策略适用于那些可以容忍短暂过期的资源。当 Service Worker 拦截到请求时,首先从缓存中返回资源,同时发起网络请求以更新缓存。这样可以在保证快速响应的同时,确保资源的及时更新。
// www.javascriptcn.com code example
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(cachedResponse => {
const fetchPromise = fetch(event.request).then(networkResponse => {
caches.open('my-cache').then(cache => {
cache.put(event.request, networkResponse.clone());
});
return networkResponse;
});
return cachedResponse || fetchPromise;
})
);
});Cache Only
Cache Only 策略适用于那些完全不需要网络请求的资源,如离线应用的核心资源。当 Service Worker 拦截到请求时,只从缓存中获取资源。如果缓存中没有,则返回错误。
// www.javascriptcn.com code example
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
if (!response) {
throw new Error('No cached response available');
}
return response;
})
);
});Network Only
Network Only 策略适用于那些必须从网络获取的资源,如实时数据。当 Service Worker 拦截到请求时,只从网络请求资源,不使用缓存。
self.addEventListener('fetch', event => {
event.respondWith(fetch(event.request));
});通过合理选择和使用这些缓存策略,可以显著提升 Web 应用的性能和用户体验。