离线缓存策略:CacheFirst 与 NetworkFirst
使用 Cache API 和 Workbox 库,为静态资源实现 Cache-First,为 API 响应实现 Network-First。
离线缓存策略:CacheFirst 与 NetworkFirst 是 CoddyKit 上的免费 Frontend Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Frontend Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Frontend Academy 课程共包含 4 节课。
缓存策略为何重要
服务工作线程可以拦截每次获取请求,但您需要制定策略。不同内容需要不同规则:标志应永久保存于缓存中,API 响应应始终保持最新,新闻文章则适合采用先返回旧缓存、再验证更新的策略。
Cache API
服务工作线程使用 Cache API:这是一个按来源划分、用于存储 Request → Response 对的键值存储。数据会跨会话持久保存。
// open a cache:
const cache = await caches.open('v1');
// add resources:
await cache.add('/styles.css');
await cache.addAll(['/', '/app.js', '/styles.css']);
// look up:
const response = await cache.match('/styles.css');
// delete:
await cache.delete('/styles.css');缓存优先
先检查 cache。找到后就返回;找不到时则回退到网络,并将响应存入 cache。最适合:静态资源、字体、标志和应用外壳。
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then(cached => {
if (cached) return cached;
return fetch(event.request).then(res => {
const clone = res.clone();
caches.open('v1').then(c => c.put(event.request, clone));
return res;
});
})
);
});网络优先
先尝试 network。如果失败(处于离线状态),则回退到 cache。最适合:API 调用,以及新鲜度比速度更重要的动态内容。
self.addEventListener('fetch', (event) => {
event.respondWith(
fetch(event.request).then(res => {
const clone = res.clone();
caches.open('api-v1').then(c => c.put(event.request, clone));
return res;
}).catch(() => caches.match(event.request))
);
});先返回旧缓存,再验证更新
立即返回 cache(速度快),然后在后台获取最新内容并更新 cache,供下次使用。最适合:头像、新闻文章和半新鲜数据。
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then(cached => {
const network = fetch(event.request).then(res => {
caches.open('v1').then(c => c.put(event.request, res.clone()));
return res;
});
return cached || network;
})
);
});仅使用网络
完全绕过 cache——始终访问 network。适用于不可缓存的请求(身份验证端点、分析请求和数据变更)。
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('/api/auth')) {
event.respondWith(fetch(event.request));
return;
}
// ... other strategies
});仅使用缓存
永不访问 network——返回 cache,否则失败。适用于已预缓存且不希望在会话期间刷新的文件。
Workbox 策略
Workbox 将所有策略打包为具名类,从而减少样板代码。
import { registerRoute } from 'workbox-routing';
import { CacheFirst, NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies';
registerRoute(({ request }) => request.destination === 'image',
new CacheFirst({ cacheName: 'images' })
);
registerRoute(({ url }) => url.pathname.startsWith('/api/'),
new NetworkFirst({ cacheName: 'api', networkTimeoutSeconds: 3 })
);
registerRoute(({ request }) => request.destination === 'document',
new StaleWhileRevalidate({ cacheName: 'pages' })
);缓存过期
除非设置限制,否则缓存会无限增长。Workbox 提供了 ExpirationPlugin。
import { ExpirationPlugin } from 'workbox-expiration';
new CacheFirst({
cacheName: 'images',
plugins: [new ExpirationPlugin({
maxEntries: 50,
maxAgeSeconds: 30 * 24 * 60 * 60 // 30 days
})]
});可缓存的响应
默认情况下,浏览器只缓存状态码为 200 的响应。请跳过 4xx、5xx 以及不透明响应(跨来源 no-cors 响应),避免错误响应填满缓存。
离线备用页面
导航失败时显示友好的离线页面——这比浏览器默认的错误页面提供更好的用户体验。
self.addEventListener('install', (e) => {
e.waitUntil(caches.open('offline').then(c => c.add('/offline.html')));
});
self.addEventListener('fetch', (e) => {
if (e.request.mode === 'navigate') {
e.respondWith(
fetch(e.request).catch(() => caches.match('/offline.html'))
);
}
});选择正确的策略
静态资源(标志、字体、CSS):缓存优先。API 数据(用户资料、信息流):网络优先。偶尔需要更新的内容(头像、新闻):先返回旧缓存,再验证更新。身份验证:仅使用网络。预安装的静态文件:仅使用缓存。
快速检查
对于很少变化但必须快速加载的 CSS 文件,哪种缓存策略最合适?
回顾:缓存策略
缓存优先:静态资源(最快,但可能过时)。网络优先:API 数据(最新,但较慢)。先返回旧缓存,再验证更新:提供缓存内容并在后台获取最新内容。仅使用网络:身份验证和数据变更。仅使用缓存:预安装的应用外壳。使用 Workbox 减少样板代码。设置过期限制。添加离线备用页面。根据资源类型选择策略。
常见问题解答
「离线缓存策略:CacheFirst 与 NetworkFirst」课时是免费的吗?
是的 — 「离线缓存策略:CacheFirst 与 NetworkFirst」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Frontend Academy 课程的其余内容,请升级到 CoddyKit PRO。 Frontend Academy 课程共包含 4 节课。
「离线缓存策略:CacheFirst 与 NetworkFirst」这节课中我会学到什么?
使用 Cache API 和 Workbox 库,为静态资源实现 Cache-First,为 API 响应实现 Network-First。 你通过在浏览器中直接运行的动手代码来练习 Frontend Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Frontend Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Frontend Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「离线缓存策略:CacheFirst 与 NetworkFirst」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Frontend Academy 课中编写并运行代码吗?
能。每节 Frontend Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- Web 应用清单
- Service Worker 注册与生命周期
- 离线缓存策略:CacheFirst 与 NetworkFirst
- 推送通知