I’m trying to cache images in my web app so users can still view them when they go offline. The images come from Airtable and I need to preload several hundred of them.
// My image caching function
const cacheImageFile = (imageUrl) => {
return new Promise((done) => {
const picture = new Image();
picture.src = imageUrl;
picture.addEventListener('load', done);
picture.addEventListener('error', done); // Continue even if loading fails
});
};
The weird thing is that when my app tries to show these images later, it acts like they were never cached and tries to download them again. Without internet, the images just don’t show up.
I tried loading them in smaller groups but that didn’t help either. Sometimes it works for a single image but not consistently. The strange part is that all these image URLs work perfectly when I have good internet and don’t try to cache them first.
Could the fact that I’m getting these images from Airtable be causing issues with the caching? Has anyone run into similar problems with image preloading?
Had this exact frustration with a project last year. The issue you’re hitting is that browser caching and programmatic image preloading are completely different things. When you create an Image object and set its src, the browser downloads it but there’s no guarantee it stays cached once that object gets garbage collected.
What worked for me was using a service worker to intercept image requests. The service worker caches responses properly and serves them when offline. You register URLs you want cached, and when the browser requests those images later, the service worker serves them from cache instead of hitting the network.
Airtable isn’t your problem - I’ve cached images from various CDNs and APIs without issues. The real problem is relying on the Image constructor for persistent caching. Service workers give you way more control over what gets cached and for how long, plus they work consistently across page reloads and browser sessions.
This makes sense once you get how browser memory works. The Image() constructor loads images but doesn’t guarantee they’ll stick around, especially with hundreds of them. I hit the same issue building an offline gallery app. Here’s the thing - browsers don’t cache programmatically loaded images the same way as regular ones. Plus, loading hundreds of images creates memory pressure that kicks out earlier cached ones. First, check your cache headers. Some APIs send cache-control headers that kill caching. Look at your network tab and see what Airtable’s sending. If they’re using no-cache or short expiration times, that’s your problem. Try a two-stage approach - keep your current preloading method but add localStorage to track which images you’ve actually cached successfully. That way you can verify what’s available offline before trying to display anything.
Been down this road myself and hit the same wall. The Image() constructor doesn’t actually cache images for offline use like you’d think.
Here’s what’s happening: the browser might store the image in memory temporarily, but it won’t persist it for offline access. When you go offline, it still tries to fetch from the network.
I solved this exact problem using the Cache API:
const cacheImageFile = async (imageUrl) => {
const cache = await caches.open('image-cache-v1');
const response = await fetch(imageUrl);
await cache.put(imageUrl, response);
};
When you need to display the images, check the cache first:
const getCachedImage = async (imageUrl) => {
const cache = await caches.open('image-cache-v1');
const cachedResponse = await cache.match(imageUrl);
if (cachedResponse) {
return URL.createObjectURL(await cachedResponse.blob());
}
return imageUrl; // fallback to original URL
};
This actually stores images in the browser’s cache storage, not just memory. Works great for hundreds of images and survives browser restarts.
Airtable URLs aren’t the issue here - it’s just that the Image() constructor isn’t designed for persistent offline caching.
Yeah, this gotcha gets everyone at first. The image() constructor just starts a download - it doesn’t actually make the browser cache it permanently. It’s more like “hey browser, grab this” instead of “save this for offline use”. Even when images appear cached initially, they get dumped fast, especially on mobile browsers that aggressively manage memory.