将响应映像脱机回退到最大缓存映像



我有一个使用srcset进行图像处理的项目。它们都在自己的子目录中,类似于:

  • /images/image1/100.jpg、200.jpg、500.jpg、1000.jpg
  • /images/image2/100.jpg、200.jpg、500.jpg、1000.jpg

该网站在列表和详细视图中使用不同大小的图像。例如,从纵向移动到横向将从100.jpg更改为200.jpg,详细视图将使用500或1000.jpg,具体取决于视口大小。

在离线场景中,是否可以让工作簿查找以"开头的URI缓存的内容/images/image1/";找到编号最高的文件并返回?如果离线用户从纵向更改为横向,我更愿意使用较小(或较大(的图像,而不是损坏的图像。

当然!这里有一个自定义插件,它需要Workbox v6,并利用新的handlerDidError生命周期事件来提供回退:

import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
// Replace with your desired cache name.
const imagesCacheName = 'images-cache';
function parseImageNameAndSize(url) {
const pattern = new RegExp('/([^/]+)/(\d+)\.jpg$');
const [_, name, size] = pattern.exec(url) || [];
// This will return [undefined, NaN] when there's no match.
return [name, parseInt(size)];
}
async imageFallback({error, request}) {
let largestSize = -1;
let cacheKeyOfLargestImage;
const [originalName, _] = parseImageNameAndSize(request.url);
// If the URL doesn't match our RegExp, re-throw the underlying error.
if (!originalName) {
throw error;
}
const cache = await caches.open(imagesCacheName);
const cachedRequests = await cache.keys();
// Iterate through all of the cache entries to find matches:
for (const cachedRequest of cachedRequests) {
const [name, size] = parseImageNameAndSize(cachedRequest.url);
if ((name === originalName) && (size > largestSize)) {
largestSize = size;
cacheKeyOfLargestImage = cachedRequest;
}
}
if (cacheKeyOfLargestImage) {
// If we have the cache key for the largest image that meets
// the conditions, return the cached response.
return cache.match(cacheKeyOfLargestImage);
}
// If there is no image the cache that satisfies these conditions,
// re-throw the underlying error.
throw error;
}
// Now, use the callback as a plugin by associating it with
// handerDidError in the strategy of your choice
// (CacheFirst, StaleWhileRevalidate, etc.):
registerRoute(
// Match any request whose path ends in .jpg
({url}) => url.pathname.endsWith('.jpg'),
new CacheFirst({
cacheName: imagesCacheName,
plugins: [
{handlerDidError: imageFallback},
// Add any other plugins you want.
],
})
);

(我还没有测试所有这些代码,但我认为它应该接近工作状态。如果你遇到问题,请告诉我!(

请注意,此插件将仅";"踢入";如果给定的策略不能满足对URL的原始请求,很可能是因为您处于脱机状态,并且没有缓存匹配。如果您想配置Workbox,使其在缓存中可用时始终使用最高质量的图像,即使您处于联机状态或缓存与低质量图像匹配时,也可以这样做(可能在cachedResponseWillBeUsed回调中(。但我认为对于您描述的特定用例,使用新的handlerDidError回调是最好的方法。

最新更新