motion-anything 本地优先模式下的缓存配置与离线验证

文章导读
motion-anything 在本地优先模式下,资源会优先从缓存读取,但缓存不会自动产生。要判断离线是否可用,需要先确认加载来源,再通过 Service Worker 显式缓存动效文件,并用 DevTools 模拟离线验证。
📋 目录
  1. 检查动效资源在本地优先模式下的加载来源
  2. 配置 Service Worker 缓存动效文件
  3. 设置缓存版本号与更新策略
  4. 用 DevTools 模拟离线并重载页面
  5. 处理缓存未命中的错误回退
A A

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 事件中清理旧缓存。

motion-anything 本地优先模式下的缓存配置与离线验证
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 返回),控制台没有未捕获的加载失败错误。如果需要动效仍然可用,建议在页面逻辑中检测到降级响应时,切换为静态占位动效。