Choose the correct level of compression

Images often account for most of the downloaded bytes on a web page and also often occupy a significant amount of visual space. As a result, optimizing images can often yield some of the largest byte savings and performance improvements for your website: the fewer bytes the browser has to download, the less competition there is for the client's bandwidth and the faster the browser can download and render useful content on the screen.

Image optimization is both an art and science: an art because there is no one definitive answer for how best to compress an individual image, and a science because there are many well developed techniques and algorithms that can significantly reduce the size of an image. Finding the optimal settings for your image requires careful analysis along many dimensions: format capabilities, content of encoded data, quality, pixel dimensions, and more.

Optimizing vector images

All modern browsers support Scalable Vector Graphics (SVG), which is an XML-based image format for two-dimensional graphics. You can embed the SVG markup directly on the page or as an external resource. Most vector-based drawing software can create SVG files or you can write them by hand directly in your favorite text editor.

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.2" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
    x="0px" y="0px" viewBox="0 0 612 792" xml:space="preserve">
<g id="XMLID_1_">
  <g>
    <circle fill="red" stroke="black" stroke-width="2" stroke-miterlimit="10" cx="50" cy="50" r="40"/>
  </g>
</g>
</svg>

The above example renders the below simple circle shape with a black outline and red background and was exported from Adobe Illustrator.

<?xml version="1.0" encoding="utf-8"?>

As you can tell, it contains a lot of metadata, such as layer information, comments, and XML namespaces that are often unnecessary to render the asset in the browser. As a result, it is always a good idea to minify your SVG files by running through a tool like SVGO.

Case in point, SVGO reduces the size of the above SVG file generated by Illustrator by 58%, taking it from 470 to 199 bytes.

<svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 612 792"><circle fill="red" stroke="#000" stroke-width="2" stroke-miterlimit="10" cx="50" cy="50" r="40"/></svg>

Because SVG is an XML-based format, you can also apply GZIP compression to reduce its transfer size—make sure your server is configured to compress SVG assets!

A raster image is simply a two-dimensional grid of individual "pixels"—for example, a 100x100 pixel image is a sequence of 10,000 pixels. In turn, each pixel stores the "RGBA" values: (R) red channel, (G) green channel, (B) blue channel, and (A) alpha (transparency) channel.

Internally, the browser allocates 256 values (shades) for each channel, which translates to 8 bits per channel (2 ^ 8 = 256), and 4 bytes per pixel (4 channels x 8 bits = 32 bits = 4 bytes). As a result, if we know the dimensions of the grid we can easily calculate the filesize:

  • 100x100 pixel image is composed of 10,000 pixels
  • 10,000 pixels x 4 bytes = 40,000 bytes
  • 40,000 bytes / 1024 = 39 KB
Dimensions Pixels File size
100 x 100 10,000 39 KB
200 x 200 40,000 156 KB
300 x 300 90,000 351 KB
500 x 500 250,000 977 KB
800 x 800 640,000 2500 KB

39 KB for a 100x100 pixel image may not seem like a big deal, but the filesize quickly explodes for larger images and makes image assets both slow and expensive to download. This post has so far only focused on the "uncompressed" image format. Thankfully, a lot can be done to reduce the image file size.

One simple strategy is to reduce the "bit-depth" of the image from 8 bits per channel to a smaller color palette: 8 bits per channel gives us 256 values per channel and 16,777,216 (256 ^ 3) colors in total. What if you reduce the palette to 256 colors? Then you would only need 8 bits in total for the RGB channels and immediately save two bytes per pixel—that's 50% compression savings over the original 4 bytes per pixel format!