首页 > 解决方案 > 我可以使用服务人员预加载特定资产吗?

问题描述

我是服务人员的新手,仍然不确定他们是如何工作的。

我正在使用 react、ES6、Typescript 构建一个教育游戏。该游戏最终将拥有大量资产,例如 Adob​​e Animate 导出的动画、音频文件等。

我想在游戏开始前为单个关卡预加载所有资产。我一直在搞乱Workbox,但我不确定它是否允许根据用户所处的游戏级别预加载特定资产。换句话说,如果用户在关卡 1,我想为关卡 1 预加载所有资产,最终,在游戏开始后,为关卡 2 预加载所有资产,这样用户就不必在关卡 1 完成后等待.

服务人员和/或 Workbox 可以做到这一点吗?

标签: service-workerworkbox

解决方案


Workbox支持预缓存一组在构建时派生的 URL。对于可能具有数兆字节内容的应用程序,最佳实践是仅缓存您认为大多数用户最终会使用的资产。

听起来,在您的场景中,预缓存在整个 Web 应用程序中常见的共享 HTML、JavaScript 和 CSS 是有意义的,然后对特定于关卡的资产使用不同的策略。

您可以直接使用缓存存储 API(在您的 Web 应用程序的window上下文中,或在您的服务工作者内部)在预缓存步骤之外将 URL 添加到缓存中。

我建议做的是利用缓存存储 API 在您的 Web 应用程序中满足某些条件时主动将项目添加到缓存中(例如,用户即将完成第 1 级),然后使用缓存优先(或 stale-while-revalidate,如果您想在 Workbox 中包含对缓存资源的更新检查)策略以及与这些 URL 匹配的路由。如果给定的资产已经被添加到缓存中,那么它将被立即使用,如果资产没有被添加到缓存中(因为用户在cache.addAll()调用完成之前从级别 1 前进到级别 2),事情仍然可以工作,但它们将在网络上被阻止。

window在您的 Web 应用程序的上下文中,这可能如下所示:

const level2Urls = [
  '/assets/level2.png',
  // ...
];

const level3Urls = [
  '/assets/level3.png',
  // ...
];

async function cacheAssetUrls(urls) {
  const cache = await caches.open('assets');
  await caches.addAll(urls);
}

然后在您的服务人员中:

workbox.routing.registerRoute(
  new RegExp('/assets/')
  workbox.strategies.cacheFirst({
    cacheName: 'assets'
  })
);

推荐阅读