Add catalog bootstrap endpoint, portrait thumbnail pipeline, lazy queued timeline images, gzip compression, and 3D texture throttling with code-split VirtualGallery.
55 lines
1.1 KiB
TypeScript
55 lines
1.1 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
|
|
const MAX_CONCURRENT = 6;
|
|
const queue: Array<() => void> = [];
|
|
let inFlight = 0;
|
|
|
|
function pumpQueue() {
|
|
while (inFlight < MAX_CONCURRENT && queue.length > 0) {
|
|
const next = queue.shift();
|
|
if (next) next();
|
|
}
|
|
}
|
|
|
|
function enqueueLoad(run: () => void) {
|
|
return new Promise<void>((resolve) => {
|
|
const task = () => {
|
|
inFlight++;
|
|
run();
|
|
resolve();
|
|
inFlight--;
|
|
pumpQueue();
|
|
};
|
|
queue.push(task);
|
|
pumpQueue();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Limits parallel image URL activation so hundreds of timeline portraits
|
|
* do not saturate the browser connection pool at once.
|
|
*/
|
|
export function useQueuedImageSrc(src: string | null | undefined): string | undefined {
|
|
const [activeSrc, setActiveSrc] = useState<string | undefined>(undefined);
|
|
|
|
useEffect(() => {
|
|
if (!src) {
|
|
setActiveSrc(undefined);
|
|
return;
|
|
}
|
|
|
|
let cancelled = false;
|
|
setActiveSrc(undefined);
|
|
|
|
enqueueLoad(() => {
|
|
if (!cancelled) setActiveSrc(src);
|
|
});
|
|
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [src]);
|
|
|
|
return activeSrc;
|
|
}
|