sw: add expiration to preview
parent
254672fabe
commit
92c35339f3
|
@ -1,5 +1,7 @@
|
|||
import { registerRoute } from "workbox-routing";
|
||||
import { CacheExpiration } from "workbox-expiration";
|
||||
|
||||
// Queue of requests to fetch preview images
|
||||
interface FetchPreviewObject {
|
||||
url: URL;
|
||||
fileid: number;
|
||||
|
@ -8,11 +10,20 @@ interface FetchPreviewObject {
|
|||
}
|
||||
let fetchPreviewQueue: FetchPreviewObject[] = [];
|
||||
|
||||
// Cache for preview images
|
||||
const cacheName = "images";
|
||||
let imageCache: Cache;
|
||||
(async () => {
|
||||
imageCache = await caches.open("images");
|
||||
imageCache = await caches.open(cacheName);
|
||||
})();
|
||||
|
||||
// Expiration for cache
|
||||
const expirationManager = new CacheExpiration(cacheName, {
|
||||
maxAgeSeconds: 3600 * 24 * 7, // days
|
||||
maxEntries: 20000, // 20k images
|
||||
});
|
||||
|
||||
// Start fetching with multipreview
|
||||
let fetchPreviewTimer: any;
|
||||
async function flushPreviewQueue() {
|
||||
if (fetchPreviewQueue.length === 0) return;
|
||||
|
@ -21,6 +32,13 @@ async function flushPreviewQueue() {
|
|||
const fetchPreviewQueueCopy = fetchPreviewQueue;
|
||||
fetchPreviewQueue = [];
|
||||
|
||||
// Check if only one request
|
||||
if (fetchPreviewQueueCopy.length === 1) {
|
||||
const p = fetchPreviewQueueCopy[0];
|
||||
return p.callback(await fetch(p.url));
|
||||
}
|
||||
|
||||
// Create aggregated request body
|
||||
const files = fetchPreviewQueueCopy.map((p) => ({
|
||||
fileid: p.fileid,
|
||||
x: Number(p.url.searchParams.get("x")),
|
||||
|
@ -41,11 +59,13 @@ async function flushPreviewQueue() {
|
|||
url.searchParams.delete("a");
|
||||
url.searchParams.delete("c");
|
||||
|
||||
// Fetch multipreview
|
||||
const res = await fetch(url, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(files),
|
||||
});
|
||||
|
||||
// Get blob
|
||||
if (res.status !== 200) throw new Error("Error fetching multi-preview");
|
||||
const blob = await res.blob();
|
||||
|
||||
|
@ -85,7 +105,7 @@ async function flushPreviewQueue() {
|
|||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.error("Multipreview error", e);
|
||||
}
|
||||
|
||||
// Initiate callbacks for failed requests
|
||||
|
@ -99,9 +119,10 @@ async function flushPreviewQueue() {
|
|||
});
|
||||
}
|
||||
|
||||
// Intercept preview requests
|
||||
registerRoute(
|
||||
/^.*\/apps\/memories\/api\/image\/preview\/.*/,
|
||||
async ({ url }) => {
|
||||
async ({ url, request }) => {
|
||||
// Check if in cache
|
||||
const cache = await imageCache?.match(url);
|
||||
if (cache) return cache;
|
||||
|
@ -122,13 +143,20 @@ registerRoute(
|
|||
}
|
||||
});
|
||||
|
||||
// Fallback to single request
|
||||
if (res.status !== 200) {
|
||||
res = await fetch(url);
|
||||
}
|
||||
|
||||
// Cache response
|
||||
if (res.status === 200) {
|
||||
imageCache?.put(url, res.clone());
|
||||
imageCache?.put(request, res.clone());
|
||||
expirationManager.updateTimestamp(request.url);
|
||||
}
|
||||
|
||||
// Run expiration once in every 20 requests
|
||||
if (Math.random() < 0.05) {
|
||||
expirationManager.expireEntries();
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
Loading…
Reference in New Issue