80 lines
1.7 KiB
TypeScript
80 lines
1.7 KiB
TypeScript
/**
|
|
* Global image loading queue service to prevent hitting browser connection limits
|
|
*/
|
|
|
|
// Configuration
|
|
const MAX_CONCURRENT_LOADS = 5;
|
|
|
|
// State
|
|
let activeLoads = 0;
|
|
const imageQueue: Array<{
|
|
element: HTMLImageElement;
|
|
onComplete: () => void;
|
|
}> = [];
|
|
|
|
/**
|
|
* Queue an image for loading, respecting the global concurrent loading limit
|
|
*/
|
|
export function queueImageForLoading(
|
|
element: HTMLImageElement,
|
|
onComplete?: () => void
|
|
) {
|
|
if (!element.dataset.src) {
|
|
console.warn("[ImageLoader] Element has no data-src attribute");
|
|
return;
|
|
}
|
|
|
|
// Add to queue
|
|
imageQueue.push({
|
|
element,
|
|
onComplete: onComplete || (() => {}),
|
|
});
|
|
|
|
// Try to process queue
|
|
processQueue();
|
|
}
|
|
|
|
/**
|
|
* Process the next items in the queue if we have capacity
|
|
*/
|
|
function processQueue() {
|
|
// Load more images if we have capacity and images in the queue
|
|
while (activeLoads < MAX_CONCURRENT_LOADS && imageQueue.length > 0) {
|
|
const next = imageQueue.shift();
|
|
if (next) {
|
|
loadImage(next.element, next.onComplete);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Internal function to handle the actual image loading
|
|
*/
|
|
function loadImage(element: HTMLImageElement, onComplete: () => void) {
|
|
// Increment active loads counter
|
|
activeLoads++;
|
|
|
|
const src = element.dataset.src;
|
|
console.debug(`[ImageLoader] Loading ${src}`);
|
|
|
|
// Start loading the image
|
|
element.src = src!;
|
|
|
|
// Handle load completion
|
|
const handleCompletion = () => {
|
|
activeLoads--;
|
|
onComplete();
|
|
processQueue();
|
|
};
|
|
|
|
// Set handlers
|
|
element.onload = () => {
|
|
console.debug(`[ImageLoader] Loaded ${src}`);
|
|
handleCompletion();
|
|
};
|
|
|
|
element.onerror = () => {
|
|
console.error(`[ImageLoader] Failed to load ${src}`);
|
|
handleCompletion();
|
|
};
|
|
}
|