motion-anything 在本地优先模式下,资源会优先从缓存读取,但缓存不会自动产生。要判断离线是否可用,需要先确认加载来源,再通过 Service Worker 显式缓存动效文件,并用 DevTools 模拟离线验证。
本地优先不代表离线自动可用:需要配置 Service Worker 显式缓存动效文件,并通过版本号控制更新。用 Network 面板可确认加载来源(from disk cache 或 Service Worker),在 Application 面板切换 Offline 可验证。若缓存未命中,必须在 fetch 事件中提供回退,否则动效会静默失败。
检查动效资源在本地优先模式下的加载来源
打开 DevTools 的 Network 面板,刷新页面,筛选动效资源请求(.js、.css、字体、图片)。点击请求,在 Network 标签或 Size 列查看来源。
- 显示
(from disk cache)或(from memory cache):资源由浏览器 HTTP 缓存返回。 - 显示
ServiceWorker:资源由 Service Worker 返回,说明正在进行缓存控制。 - 显示具体字节数且没有缓存标记:资源从网络加载。
如果动效文件始终显示网络请求,说明本地优先尚未生效,需要配置缓存。
配置 Service Worker 缓存动效文件
在项目根目录创建 service-worker.js,列出需要预缓存的动效文件。这里以常用动效库和配置为例:
const CACHE_NAME = 'motion-cache-v1';
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME).then(cache => {
return cache.addAll([
'/motion-anything.js',
'/animations/fade.json',
'/animations/scale.json'
]);
})
);
});在页面入口注册 Service Worker:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js');
}注册后,首次访问会预缓存这些文件,离线时可直接使用。
设置缓存版本号与更新策略
动效文件更新后,需要避免旧缓存被继续使用。修改 CACHE_NAME 中的版本号,并在 activate 事件中清理旧缓存。
const CACHE_NAME = 'motion-cache-v2';
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(keys => {
return Promise.all(
keys.filter(key => key !== CACHE_NAME)
.map(key => caches.delete(key))
);
})
);
});每次更新动效,递增版本号即可。注意,版本号必须与缓存列表一起发布。
用 DevTools 模拟离线并重载页面
打开 DevTools,点击 Network 面板,在 Throttling 下拉框选择 Offline,然后刷新页面。
- 动效正常渲染,控制台无资源加载错误:缓存生效。
- 控制台出现
Failed to fetch或脚本执行错误:部分依赖未缓存,需补充列表。
也可以在 Application 面板的 Service Workers 区域勾选 Offline,注意与 Network 切换的区别——Application 的 Offline 仅模拟 Service Worker 的网络访问。
处理缓存未命中的错误回退
当动效文件不在缓存且网络失败时,需要返回备选内容。在 fetch 事件中增加兜底逻辑:
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(cached => {
if (cached) return cached;
return fetch(event.request).catch(() => {
// 脚本资源返回占位内容,避免执行错误
if (event.request.destination === 'script') {
return new Response('// offline fallback', {
status: 200,
headers: { 'Content-Type': 'text/javascript' }
});
}
// 其他资源返回提示
return new Response('offline', {
status: 503,
headers: { 'Content-Type': 'text/plain' }
});
});
})
);
});验证降级行为:在 Offline 模式刷新,观察 Network 面板中未缓存的脚本请求显示为 200(由 Service Worker 返回),控制台没有未捕获的加载失败错误。如果需要动效仍然可用,建议在页面逻辑中检测到降级响应时,切换为静态占位动效。