Skip to content
John R Cottam

Progressive Image Loading with Cloudinary

How to use Cloudinary's real-time image transformations to serve low-quality placeholders before high-quality images load — reducing flicker, bandwidth, and perceived wait time.

John Ryan Cottam

2 min read

Progressive Image Loading with Cloudinary

Progressive image loading is the process of serving a tiny, low-quality placeholder while the full-resolution image loads in the background. It’s a simple technique with a meaningful payoff — especially on image-heavy pages like feeds or galleries.

Why it matters

Without placeholders, <img> tags default to 0×0 until they load. The page jumps. Users wait. First impressions suffer.

Low-quality placeholders solve four things at once:

  • No layout shift — the container holds its space, so the page doesn’t flinch as images arrive
  • Faster perceived load — a tiny placeholder (say, 25KB vs 210KB) downloads in a fraction of the time
  • Bandwidth savings — pair this with lazy loading and full-size images only download when they’re actually needed
  • A natural transition hook — the swap from placeholder to final image is the perfect moment for a smooth fade

Cloudinary does the heavy lifting

Cloudinary transforms images on the fly via URL parameters. No preprocessing, no extra build step. You request the same image twice — once blurred and degraded, once full quality — and Cloudinary handles both.

Low-quality placeholder — blurred, grayscale, low fidelity:

e_blur:1000/w_478,h_300,c_thumb,e_grayscale,q_auto:low

High-quality image — full color, full fidelity:

w_478,h_300,c_thumb,q_auto

You can test this today without an account. Cloudinary’s demo account supports their Fetch API, which proxies any public image URL through their transformation pipeline:

https://res.cloudinary.com/demo/image/fetch/e_blur:1000/e_grayscale,w_400,h_400,q_auto:low/https://unsplash.it/400/400

Implementation

The key is a wrapper <div> that holds both images — placeholder and final — and prevents layout shift while they load.

Set the container to position: relative with a padding-bottom percentage matching the image’s aspect ratio. Images are positioned absolute inside it. This reserves the exact space the image will occupy before a single pixel loads.

Aspect ratio to padding-bottom:

/* 16:9 */
padding-bottom: 56.25%;

/* 4:3 */
padding-bottom: 75%;

/* 1:1 */
padding-bottom: 100%;

Sequence of events:

  1. Render the low-quality placeholder immediately — it’s tiny, it loads fast
  2. Start loading the high-quality image with visibility: hidden; opacity: 0
  3. On load, fade it in — the placeholder disappears naturally underneath

Take it further

This technique pairs well with lazy loading. If you’re building a feed or any page with many images, don’t load high-quality versions until they’re actually in the viewport. The placeholder holds the space; the full image downloads only when it’s needed.

Sign up for a free Cloudinary account and start experimenting — the URL-based transformation API makes iteration fast.

Subscribe to my notes

Stay in the loop on what I'm building and thinking about.