一种很常见的做法是,限制缓存应允许项目存储在缓存中的时长,或者缓存中应保留多少项。Workbox 通过 workbox-expiration
插件提供此功能,您可以限制缓存中的条目数并 / 或移除长期缓存的条目。
限制缓存条目的数量
如需限制存储在缓存中的条目数,您可以使用 maxEntries
选项,如下所示:
import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {ExpirationPlugin} from 'workbox-expiration';
registerRoute(
({request}) => request.destination === 'image',
new CacheFirst({
cacheName: 'image-cache',
plugins: [
new ExpirationPlugin({
maxEntries: 20,
}),
],
})
);
这样,插件就会添加到此路由中。使用缓存的响应或将新请求添加到缓存后,插件将查看已配置的缓存,并确保缓存的条目数不超过限制。否则,最早的条目将被移除。
限制缓存条目的存在时间
如需限制请求的缓存时长,您可以使用 maxAgeSeconds
选项定义最长存在时间(以秒为单位),如下所示:
import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {ExpirationPlugin} from 'workbox-expiration';
registerRoute(
({request}) => request.destination === 'image',
new CacheFirst({
cacheName: 'image-cache',
plugins: [
new ExpirationPlugin({
maxAgeSeconds: 24 * 60 * 60,
}),
],
})
);
该插件会在每次请求或缓存更新后检查并移除条目。
高级用法
如果您希望将到期逻辑与任何其他 Workbox 模块分开使用,可以使用 CacheExpiration
类来实现此目的。
如需对缓存应用限制,您需要为要控制的缓存创建 CacheExpiration
实例,如下所示:
import {CacheExpiration} from 'workbox-expiration';
const cacheName = 'my-cache';
const expirationManager = new CacheExpiration(cacheName, {
maxAgeSeconds: 24 * 60 * 60,
maxEntries: 20,
});
每当更新缓存条目时,您都需要调用 updateTimestamp()
方法,以便更新其存在时间。
await openCache.put(request, response);
await expirationManager.updateTimestamp(request.url);
然后,每当您想要使一组条目过期时,您可以调用 expireEntries()
方法,该方法将强制执行 maxAgeSeconds
和 maxEntries
配置。
await expirationManager.expireEntries();
类型
CacheExpiration
借助 CacheExpiration
类,您可以定义 Cache
中存储的响应数量的到期时间和 / 或限制。
属性
-
构造函数
void
如需构造新的 CacheExpiration 实例,您必须至少提供其中一个
config
属性。constructor
函数如下所示:(cacheName: string, config?: CacheExpirationConfig) => {...}
-
cacheName
string
要应用限制的缓存的名称。
-
config
CacheExpirationConfig 可选
-
-
删除
void
移除用于跟踪缓存过期元数据的 IndexedDB 对象存储。
delete
函数如下所示:() => {...}
-
返回
Promise<void>
-
-
expireEntries
void
过期给定缓存和给定条件的条目。
expireEntries
函数如下所示:() => {...}
-
返回
Promise<void>
-
-
isURLExpired
void
可用于在使用网址之前检查网址是否已过期。
这需要从 IndexedDB 进行查询,因此速度可能会很慢。
注意:此方法不会移除缓存条目,而是调用
expireEntries()
来移除 indexDB 和 Cache 条目。isURLExpired
函数如下所示:(url: string) => {...}
-
网址
string
-
返回
Promise<boolean>
-
-
updateTimestamp
void
更新指定网址的时间戳。这可确保在根据条目数上限(最近使用的条目)移除条目时,或者在过期条目到期时是最新的时间戳。
updateTimestamp
函数如下所示:(url: string) => {...}
-
网址
string
-
返回
Promise<void>
-
ExpirationPlugin
此插件可在 workbox-strategy
中使用,以定期对年龄和 / 或缓存请求数施加限制。
它只能与自定义 cacheName
属性集的 workbox-strategy
实例搭配使用。换言之,它不能用于使使用默认运行时缓存名称的策略中的条目过期。
每当使用或更新缓存的响应时,此插件都会查看关联的缓存,并移除所有旧响应或多余的响应。
使用 maxAgeSeconds
时,可以在过期后使用一次响应,因为只有在使用缓存响应之后才会执行过期清理。如果响应包含“Date”标头,则系统会执行轻量级失效检查,并且不会立即使用响应。
使用 maxEntries
时,系统会首先从缓存中移除最近最少请求的条目。
属性
-
构造函数
void
constructor
函数如下所示:(config?: ExpirationPluginOptions) => {...}
-
config
-
-
deleteCacheAndMetadata
void
此辅助方法会执行两项操作:
- 代表您调用 caches.delete() 删除与此插件实例关联的所有底层 Cache 实例。
- 从 IndexedDB 中删除用于跟踪每个缓存实例的到期详情的元数据。
使用缓存到期时,调用此方法比直接调用
caches.delete()
更可取,因为这将确保 IndexedDB 元数据也彻底移除,并删除打开的 IndexedDB 实例。请注意,如果您没有为给定的缓存使用缓存失效时间,则调用
caches.delete()
并传入缓存的名称应该就足够了。 在这种情况下,不需要使用特定于 Workbox 的方法进行清理。deleteCacheAndMetadata
函数如下所示:() => {...}
-
返回
Promise<void>
ExpirationPluginOptions
属性
-
matchOptions
CacheQueryOptions 可选
-
maxAgeSeconds
数字可选
-
maxEntries
数字可选
-
purgeOnQuotaError
布尔值 选填