Images

How Medium does progressive image loading

Recently, I was browsing a post on Medium and I spotted a nice image loading effect. First, load a small blurry image, and then transition to the large image. I found it pretty neat and wanted to dissect how it was done.

[…]

I have performed a WebPageTest test against this page on Medium where you can see how it loads too. And if you want to see it by yourself, open Medium’s post in your browser, disable the cache and throttle the response so it takes longer to fetch the images and you can see the effect.

Here is what is going on:

  1. Render a div where the image will be displayed. Medium uses a <div/> with a padding-bottom set to a percentage, which corresponds to the aspect ratio of the image. Thus, they prevent reflows while the images are loaded since everything is rendered in its final position. This has also been referred to as intrinsic placeholders.

  2. Load a tiny version of the image. At the moment, they seem to be requesting small JPEG thumbnails with a very low quality (e.g. 20%). The markup for this small image is returned in the initial HTML as an <img/>, so the browser starts fetching them right away.

  3. Once the image is loaded, it is drawn in a <canvas/>. Then, the image data is taken and passed through a custom blur() function You can see it, a bit scrambled, in the main-base.bundle JS file. This function is similar, though not identical, to StackBlur‘s blur function. At the same time, the main image is requested.

  4. Once the main image is loaded, it is shown and the canvas is hidden.

All the transitions are quite smooth, thanks to the CSS animations applied.

The "Optimal Image Format" for Each Browser

Perhaps you’ve heard about the WebP image format? And how it’s a pretty good performance win, for the browsers that support it? Well that’s only for Blink-based browsers, at the moment. Estelle Weyl’s article Image Optimization explains the best image format for each browser:

Browser Optimal image format
Chrome WebP
IE 9+ / Edge JPEG-XR
Opera WebP
Safari JPEG-2000

And you can serve these formats through the <picture><source type=""> syntax.

Couple that complexity with the complexity of responsive images, and it really seems like outsourcing image delivery to a dedicated service seems like the way to go. At least above a certain scale.