Explain Codes LogoExplain Codes Logo

Preloading images with JavaScript

javascript
image-preloading
async-programming
promise-all
Anton ShumikhinbyAnton Shumikhin·Mar 2, 2025
TLDR

To preload images swiftly, create a new Image() object and assign the src property:

const preloadImage = src => (new Image().src = src); // Preloaded images in a snap: ['img1.jpg', 'img2.jpg'].forEach(preloadImage); // Because no one likes the spinning wheel of doom!

This simple segment ensures images load swiftly when attached to the DOM.

Advanced preloading using event handlers

While the basic solution is nifty for most, occasions may demand the assurance that images have fully loaded before use. onload and onerror event handlers are perfect in this context:

const preloadImageWithEvents = (src, callback) => { const img = new Image(); img.onload = () => callback(null, src); // On your mark, get set, loaded! img.onerror = error => callback(error, src); // Sometimes 'oops' is the only correct response img.src = src; };

Leverage Promise.all to handle image preloading in parallel, providing better control over asynchronous image loading:

const imageSources = ['img1.jpg', 'img2.jpg']; const imagePromises = imageSources.map(src => { return new Promise((resolve, reject) => { preloadImageWithEvents(src, (error) => { if(error) reject(error); else resolve(); }); }); }); Promise.all(imagePromises) .then(() => console.info('All images preloaded. Woohoo!')) .catch(error => console.error('Preloading failed. BOOM!', error)); // Unexpected kaboom?

Comprehensive browser compatibility techniques

Browsers can be a mixed bag of behaviors, but these key techniques should have you covered:

  1. Utilize the <link> tag:
<link rel="preload" href="img1.jpg" as="image"> <!-- Much better than Snail Mail -->
  1. Harness JavaScript preloading for dynamic preloading:
function preloadImages(urls) { urls.forEach(preloadImage); // foreach = for fast car in the race! }
  1. Monitor progress to handle large sets of images effectively:

Utilize counter variables for simple tracking or use Promise for handling asynchronous image loading.

Managing compatibility issues

The <link> element with rel="preload" is a modern, proactive approach that works great with most browsers. For contingency, supplement it with JavaScript preloading as a fallback for legacy browsers.

Working with large image sets

Handfuls of images are fairly easy to manage. But, what about hundreds?

  • Bundle them in batches to avoid exhausting the browser's resources.
  • Prioritize based on importance and visibility.
  • Keep a close eye on memory usage, especially on the user side.

Debugging your preload process

If preloading goes off track, here are some ways to debug:

  • Use console.log() to trace the preload progress.
  • Invoke onerror to detect and log errors for each image. It's not much, but it's honest work.
  • Monitor the network panel in your dev tools to verify if your images are loaded.

Account for slow connections

Remember, not all users have high-speed internet. To smooth out the experience for slower connections:

  • Use low-quality image placeholders.
  • Gradually replace with high-res images post-preload.
  • Offer progressive loading indicators.