Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Optimized Lazy Image Loading with Progressive JPEG and HTTP Range Requests

Optimized Lazy Image Loading with Progressive JPEG and HTTP Range Requests

This item in japanese

Christoph Erdmann recently detailed an interesting technique for image lazy loading using Progressive JPEG and HTTP range requests. Websites using the technique may quickly display a minimal, recognisable, embedded image preview (EIP) through a first HTTP range request, with a delayed, second range request fetching the rest. Unlike other image placeholder and lazy loading techniques, using range requests do not result in downloading extra image data.

Addy Osmani, engineering manager working on Google Chrome, quoted a study from the HTTP Archive revealing that images may account for more than half of the content loaded for the average site. Given the positive effect of images on conversion rates, that percentage is expected to remain significant.

In the context of devices with a large spectrum of hardware and network capabilities, and with an ever-growing user base on low-end devices, web developers thus seek to optimize user experience with lazy image loading and other image optimization techniques. The importance of lazy loading is illustrated by the fact that it is now natively present in the Chrome browser since Chrome 74.

José M. Pérez, solutions engineer at Facebook, provides an infographics summarizing the existing image loading techniques:

The last strategy may present solid advantages vs. the alternatives in terms of user experience, and is often termed as LQIP (Low Quality Image Placeholder). A variant using SVG-based previews (SQIP) may also be leveraged to generate small, low-quality image previews.

However, common LQIP strategies often involve downloading two images, the preview and the actual image, resulting in extra data being fetched. Erdmann presents a strategy based on two HTTP range requests, which does not incur in data overhead.

Erdmann recommends leveraging progressive JPEG, a JPEG compression format in which an image is encoded in several passes, each successively leading to a more accurate display of the encoded image:

Erdmann mentions that the regular progressive JPEG approach comes with some caveats:

If your website consists of many JPEGs, you will notice that even progressive JPEGs load one after the other. This is because modern browsers only allow six simultaneous connections to a domain. Progressive JPEGs alone are therefore not the solution to give the user the fastest possible impression of the page. In the worst case, the browser will load an image completely before it starts loading the next one.

Erdmann’s remedy to these caveats is to use HTTP range requests. An initial HTTP request asks for the range of data which contains the first encoded pass of the Progressive JPEG. A second range request, scheduled by developers at a convenient time, may fetch the rest of the data.

Shows the way the EIP (Embedded image preview) technique loads the image data in two requests.

As no preview image needs be created, no superfluous data needs be downloaded. Furthermore, images encoded with Progressive JPEG are generally not heavier than their baseline JPEG counterpart. On the downside, Cloudinary, a popular image and video platform, reports that decoding Progressive JPEG may result in higher CPU usage than with baseline JPEG encoding, and provides mitigating techniques which adjust the number and content of passes in the Progressive JPEG encoding.

Erdmann mentions three steps to implement his recommended image loading technique.

First, the Progressive JPEG must be created. This can be achieved for instance with jpegtran:

$ jpegtran input.jpg > progressive.jpg

Second, the byte offset to determine the range of the two HTTP requests must be computed. Third, a JavaScript script must implement the lazy loading and perform and schedule the HTTP requests. The three steps may be performed manually by the developer or integrated in an automated workflow.

Erdmann provides a prototype for developers to experiment with his lazy loading technique. The prototype source code is available in a GitHub repository. Comments on the prototype are welcome and may be posted in the related blog post.

Rate this Article