eBay Tech Blog

A Picture is Worth a Thousand Words

by Raja Bhogi on 02/22/2013

in Software Engineering

Complex ideas can be conveyed with just a single image. That’s the notion of the common expression, “A picture is worth a thousand words.”

To provide rich user experiences, today’s web sites are incorporating lots of images. In most cases, these images are high resolution and have larger dimensions than in the recent past. Images contribute more to page weight than any other resource; according to httparchive.org, they represent 62% of the weight on an average web page.

Of course, as the use of images has increased so has the challenge of serving them without adversely affecting the user experience. This post addresses some of the most effective techniques for optimizing the perceived and real load times of image-rich web pages.

WebP

WebP is a new image format from Google with a 25-34% smaller file size compared to JPEG images. Currently, Chrome and Opera are the only browsers that support WebP. According to wikipedia, Chrome has a 36% share and Opera a 1% share of browser usage.

This test from webpagetest.org compares the page load time of WebP vs. JPEG. The test has one page with 50 images in the WebP format, and another page with the same 50 images in the JPEG format. Because the WebP page had to download fewer bytes (474484 vs. 757228), it completes loading much earlier compared to the JPEG page.

If you track your web site’s browser usage stats and find that Chrome/Opera users are a sizable chunk, using WebP images will improve the page load time for these users.

Progressive JPEG

A simple or “baseline” JPEG file is stored as one top-to-bottom scan of the image—whereas the progressive JPEG format divides the file into a series of scans. When a progressive JPEG loads, the user sees a low-quality image at first, but gradually sees the image at its full quality. Most of the latest browsers support progressive JPEGs. They improve the perceived loading speed when compared to baseline JPEGs, as this webpagetest.org test demonstrates.

Try progressive JPEGs for your above-the-fold images, and do A/B testing to see the impact on your site’s user experience.

Lazy loading

The most popular image optimization technique, widely used across the web, is lazy loading. This technique involves loading only a subset of the images initially, and loading the rest of the images on the scroll event or after the window on-load event. Using the on-scroll event to lazy-load images will significantly improve the page load time.

This technique might require the use of JavaScript. The only issue I see with lazy loading is that if the user loads a page through the browser’s back or forward button, JavaScript usage might cause some lag before the lazy-loaded images appear.

Image embedding (Data URI / Base64)

Each HTTP request exacts a price. Another popular technique for improving page load time is to minimize the number of HTTP requests. To improve the perceived load time, you can embed above-the-fold images using the Data URI scheme (base64). With this technique, images can be delivered as part of the page’s main payload; the HTTP request can be eliminated completely. Consider, for example, this <IMG> tag, which uses an HTTP request to display Right arrow (a right arrow):

<IMG src="http://pics.ebaystatic.com/aw/pics/help/infohubs/images/imgNaviArrowRgt_12x12.gif">

The following <IMG> tag uses the Data URI scheme to embed the image in the page:

<IMG src="data:image/gif;base64,R0lGODlhDAAMANUmACxw0RZVtClvzhxevA1OqApFoQQ/mxFMqARBnApFnxVWsipxzRZXsyFmwRxfugVIoSNlwx1fvStv0BZWsAA9lAA8lApHoA9PpwNAmSduyilsxx5dvCRlwxxevhRXsiNkwidsyRFOqSFmxQ5Nqidsyxpfuv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACYALAAAAAAMAAwAAAY6QJPQJBkajQDB8ShYAJZDUkYDgpo+EE5DBO2UNgNHZKnwBBiBwXIUOhAmUMujcLFiEAmrqWLQmyhQQQA7">

The Data URI approach has two drawbacks:  the main payload of the page is increased, and the images aren’t cached by the browser. To address the caching issue, you could deliver Data URIs via an external JavaScript or CSS file; but you might not see the same perceived speed improvement that you would if you embedded the images directly in the page.

Sprites

Sprites are another way to minimize the number of HTTP requests. With this technique, you “stitch” together different smaller images and display the stitched image on the page, using CSS background styling to show different parts of the image. Sprites are easier to implement in cases where fairly static sets of images are to be displayed. Applying this technique to dynamically constructed pages—such as a search results page, where images to be displayed can vary substantially over time—could be challenging. The stitching process would need to be on demand and very fast. Moreover, if you’re using a content delivery network (CDN), you might lose the CDN benefits, because the stitched images might not be in the CDN cache servers and so the requests would come to your app servers instead.

CDN

By serving all static resources for a web page through a CDN, you can significantly reduce the actual page load times. Instead of the static content being requested from your servers, it would be delivered from CDN cache servers that are closer to the end user. Using the same images across all of your web pages would increase the CDN cache hits.

Domain sharding

Traditionally, web browsers place a limit on the number of simultaneous connections they can make to one domain. To increase the number of simultaneous connections, you can use multiple domains to serve the resources. You would have to pay for extra DNS lookup time for these extra domains, but the benefits outweigh this overhead. Domain sharding is applicable to all external resources—not just the images.

For mobile use cases, domain sharding might not be optimal, because the connection overhead for mobile browsers exceeds the benefit of having additional simultaneous connections.

Image dimensions

Specifying the width and height of every image in the <IMG> tag or in the CSS avoids unnecessary reflows and repaints. For example:

<IMG src=” http://thumbs.ebaystatic.com/d/l225/m/mHpX0W1OpQlEaydbGwCWuOg.jpg” width=”208px” height=”126px”>

This practice improves the rendering time and provides the user with a much smoother rendering experience.

Image scaling

If you need a smaller image, scale the bigger image and create the smaller one. Avoid using width and height specifications to scale images on the fly—a practice that would require downloading unnecessary extra bytes, thereby increasing page loading time.

Here is an example of poor practice:

<IMG src=”bigimage_width300_height300.gif” width=”100px” height=”100px”>

Instead, generate a 100 x 100 image, and use it:

<IMG src=”resized_bigimage_width100_height100.gif” width=”100px” height=”100px”>

The generated image will be smaller in size.

Image pre-fetching

If you can guess the user’s next move, you can pre-fetch some images (maybe the above-the-fold images) for the next page in the idle time or after the current page is loaded. This technique would load the next page faster, since the pre-fetched images would come from the browser’s cache.

Conclusion

To provide rich content, images are king. The optimization techniques discussed in this post are widely used across the web. By adopting all or some of them, you can substantially improve the perceived and real page load times for your site. Personally, I am thrilled about WebP and progressive JPEGs, and I hope more browser providers will come on board to support WebP in the future.

{ 7 comments… read them below or add one }

Yamil Gonzales February 25, 2013 at 12:40PM

I’m not really sure about this… you’re using IMG (capitals) for your tags and suggesting width and height; those practices go against W3C recommendations, there’s a reason why XHTML+ standardized the caps and styling practices.

Reply

Nick March 4, 2013 at 2:58PM

A picture most certainly IS worth a thousand words.

This is a comprehensive article, nice work – is useful for any developer looking for food for thought on image use and alteration.

I love the blog design btw.

Reply

Dror Gill March 14, 2013 at 6:43AM

Thanks for a great post Raja! You should also check out the image optimization technology we’ve developed called JPEGmini, which gives files sizes that are smaller than WebP, have higher quality, and are in fully standard JPEG format readable by any browser or device.

Reply

Bruno George Moraes March 26, 2013 at 7:38AM

Hi, a problem with most WebP comparisons is to wrongly compare SSIM like 0.98 versus 0.96 is actualy twice as good (log scale). Even if those were corrected with DSSIM which is a distance metric and improves the situation. All objective metrics have flaws. Another problem is decoding speed of progressive jpeg is much lower in libjpeg or libjepg-turbo. Color management also slow things down. Thanks for bringing awereness to the image importance on the web.

Ratio = (1 / (1-NewSSIM)) / (1 / (1-OldSSIM))

Reply

Adam April 10, 2013 at 11:18AM

Also you’re mistakingly specifying ‘px’ units on img tag width/height attributes.

Reply

Josiah Warren December 2, 2013 at 8:58PM

A picture is worth a thousand words” refers to the notion that a complex idea can be conveyed with just a single still image. It also aptly characterizes one of the main goals of visualization, namely making it possible to absorb large amounts of data quickly.

Reply

Andrea Verlicchi November 27, 2014 at 2:52PM

Hi,
if you want to save all of your images in the progressive JPEG format and still take advantage of the Lazy Load, you can combine the two using this http://verlok.github.io/lazyload/ and setting the show_while_loading option to true.

Reply

Leave a Comment

{ 1 trackback }

Previous post:

Next post:

Copyright © 2011 eBay Inc. All Rights Reserved - User Agreement - Privacy Policy - Comment Policy