This guest post is by Adam Bradley, founder and developer of CDN Connect. He specializes in image optimization, resizing, content-aware cropping, and responsive web design, with the goal of keeping content strategies and workflows simple.tl;dr
Browsers may use the
Accept
header to indicate supported content types. This lets you serve optimized images to minimize bandwidth and improve page load, without any changes to HTML/CSS or the images themselves. Here's how:
Accept
header lets origin servers determine the best image format to send the browser It’s common to minify CSS and JavaScript files by removing whitespace and comments, renaming variables, and a few other tricks. The main benefit is reducing download times and providing visitors with a faster page load. But on the average webpage, we're overlooking the gigantic elephant in the room: images. Images can dwarf text files like CSS and JavaScript:
according to httparchive.org, they comprise over 60% of the transfer of average webpage.
GigaOM reportsthat webpages grew by 50% between November 2010 and May 2012, and estimates an average size of 2MB by 2015. Combine this growth with the increasing use of mobile devices (i.e., expensive, capped bandwidth), and we're heading in the wrong direction.
Fortunately, Google and other companies are working to reduce bandwidth usage. A major achievement is a new image format,
WebP, which handles lossy (JPEG) and lossless (PNG) images, all while reducing file sizes. According to Google:
WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller in size compared to JPEG images at equivalent SSIM index. WebP supports lossless transparency (also known as alpha channel) with just 22% additional bytes. Transparency is also supported with lossy compression and typically provides 3x smaller file sizes compared to PNG when lossy compression is acceptable for the red/green/blue color channels.
Chrome and Opera support WebP, and
Firefox is considering supportas well. With increasing adoption and bandwidth benefits, WebP may become the go-to web image format.
This is great news, but WebP raises several questions, especially for graphic designers, web designers and developers. How can we use WebP without an involved manual process? How can we serve images to browsers that don't support WebP? How can we update existing references to our
.jpg
,
.png
and
.gif
files?
Don't believe me? Let's see it in action. The example image below looks the same for all visitors: it's served as WebP if supported, and PNG otherwise. The original PNG file (exported from Photoshop) was 52kb.
But with
CDN Connect’s automatic image re-encoding, this 52kb PNG shrunk to a 11kb WebP image.
That's a 78% size reduction! Just imagine this image was referenced on every page of your site, and you had handfuls of similar images to download. The potential bandwidth savings and performance improvements are enormous. Additionally, there were no site changes:
For this image, the 78% size reduction worked extremely well. Google found the average savings around 25-34%, still a sizable improvement.
CDN Connect and
MaxCDNcollaborated to make using WebP seamless, and it boils down to using the
Accept
HTTP request header. Every browser request includes details like the software platform, cookies, language settings, and so on. For us, the
Accept
header is the key: the browser tells the server, “Hey, here are the file types I understand.”
Officially, the HTTP/1.1 protocol solved
server-driven content negotiationyears ago (fancy jargon, I know). But until recently, the
Accept
header has been overlooked by most browsers.
Ilya Grigorik, developer advocate on the
Make The Web Fasterteam at Google, summarized the
Accept
headers
sent by various browsers:
Browser | Accept Header Values |
---|---|
Chrome | */* |
Safari | */* |
Firefox | image/png,image/*;q=0.8,*/*;q=0.5 |
Internet Explorer | image/png,image/svg+xml,image/*;q=0.8, */*;q=0.5 |
Opera | text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1 |
Opera is the only browser that can both view WebP images and officially accepts the
image/webp
content type. Chrome can view WebP, but at the time of this writing, doesn’t specify it in the header. The good news is that according to
this Chromium bug,
image/webp
will be added to the
Accept
header soon (and given the amazing rate of Chrome's development, we're not worried about waiting long). The Firefox
bug for WebP supportincludes the suggestion “it would he helpful if your changes also included modifying the
Accept
header for image and HTML requests”. Because Firefox made a similar change when supporting PNG (adding
image/png
to the accept header), we imagine the same will happen for
image/webp
. In summary,
Opera supports WebPtoday,
Chrome will implementthe Accept header soon, and
Mozilla is taking a closer look.
Let's load images with Opera, which supports WebP, and see the request and response headers (screenshot below). Even though the request for "MaxCDN-WebP.png" includes
image/png
in the
Accept
header, the content-type of the response is still
image/webp
. Even though every browser requests the same url (the ".png"), the server decided the WebP format was the best one to send back. Remember, a filename is just a name: the content-type determines what sort of file it is.
Opera Dragonfly: Request and Response
Now let's try Firefox. Notice that
image/webp
is missing from the
Accept
header, and the server responds with the default image encoding (PNG). Any browser without declared WebP support will get the PNG version. Additionally, notice the file was correctly cached by Nginx (
X-Cache: HIT
).
Firefox Firebug: Request and Response
MaxCDN has a worldwide network of Nginx servers, but it can be tricky to cache different content types at the same URL as we did above (both image versions showed X-Cache: HIT). If done incorrectly, a cached WebP image could be sent to a browser that doesn't support it.
We worked with Google's
Make The Web Fasterteam and quickly found a solution. Similar to how the
Accept-Encodingheader informs the server whether the browser can handle GZIP compression, we'll use the
Accept
header to distinguish the image formats internally. Here's how MaxCDN configured Nginx to cache images:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | server { listen 80; server_name ei8gd7lwnymbl2d.cdnconnect.netdna-cdn.com jdorfman.cdnconnect.com; set $webp ""; if ($http_accept ~* image/webp) { set $webp "webp"; } location ~ /purge(/.*) { allow 192.168.0.1/24; deny all; proxy_cache_purge my_diskcached ei8gd7lwnymbl2d.cdnconnect10$myae$webp$1$is_args$args; } location / { [clipped] proxy_cache_key ei8gd7lwnymbl2d.cdnconnect10$myae$webp$uri$is_args$args; } } |
Notice how the "
$webp
" variable gives us different cache keys for the various versions. Previously, similar content negotiation required a giant database of User-Agent strings to determine browser capabilities (which, as you can imagine, needs constant maintenance for new devices and browsers). And server-driven content negotiation often results in the fragmentation of cached data, or constant image processing. But with
MaxCDN's network, you can take advantage of powerful, globally-available caching methods available today.
Modern browsers with the
Accept
header let origin servers optimize image delivery. With server-side content negotiation, your entire organization gets awesome benefits:
Want to try WebP?
CDN Connectwill dynamically convert images to WebP without any code changes, providing the benefits above. For customers who opt-in to this feature, all configuration happens automatically. CDN Connect removes the burden of image resizing, content-aware cropping, image optimisation and file format conversion, all while hosting files from a fast, worldwide content delivery network built for a team environment. Start using WebP today!