Understanding Image formats on the Web
Tags: html, webdev, webperf
Published: 2019-11-14 17:44:29

Images are probably the #1 performance bottleneck on websites. Tons of developers spend hours shaving of some kb of their bundle while serving megabytes worth of images. 

Image Optimization consists of 3 main parts:

1. Using the right image format(s)
2. Using responsive images (will be release 18.11)
3. Using Progressive/Lazy image loading (will be release 25.11)

In this series, I'll go over each off these topics so that hopefully by the end you'll have a full understanding of how images on the web work. This first part covers what format you should use for your images.

# Using the right image format(s)

There's 4 main formats you should know:

 - [jpg](#jpg-(or-jpeg,-its-the-same))
 - [png](#png)
 - [svg](#svg)
 - [webp](#webp)

Let's go through each of them

##JPG (or jpeg, its the same)
Probably the most common image format, jpg's are small and can display a wide range of colours so they're **well suited for photos**. Due to the way JPGs are compressed (which is called "lossy compression") they're pretty bad at showing sharp edges (like between the white and the black in the image below), so they're **not well suited for logos and illustrations**.

![blurry Icon](https://thepracticaldev.s3.amazonaws.com/i/gqlux85i63of2z5zup0e.png)

There's also JPEG2000 and JPEG XR which were created after the original jpg spec to improve on it, but browser support is [so](https://caniuse.com/#search=JPEG%20XR) [slim](https://caniuse.com/#search=JPEG%202000) that you shouldn't use them on the web.

##PNG
PNGs use "lossless compression" which makes them much better suited to show sharp edges. They also support opacity. The drawback is that the file size is larger than that of a JPG. You can use PNGs for illustrations and logos but there is often a better option:

##SVG
SVG stands for "scalable vector graphic". SVGs look a bit like HTML which makes them incredibly small and versatile. SVGs can be edited with CSS and animated in a lot of different ways. They can also be scaled to any size since they're not encoded in pixels (see example down below). If you have the option it's usually best to use SVG for Icons, Logos etc, but often times (especially when dealing with illustrations) you will be stuck with a PNG and you can't reliably convert a png to an svg.

This is what an svg looks like 
```
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 11.377C6.22266 11.377 6.48633 11.2715 6.73242 11.1133C9.92578 9.0625 11.9238 6.60156 11.9238 4.16992C11.9238 1.96094 10.4473 0.460938 8.53125 0.460938C7.5 0.460938 6.63281 0.953125 6 2.00781C5.36719 0.947266 4.49414 0.460938 3.46289 0.460938C1.54688 0.460938 0.0703125 1.96094 0.0703125 4.16992C0.0703125 6.60156 2.07422 9.0625 5.26172 11.1133C5.50781 11.2715 5.77148 11.377 6 11.377Z" fill="currentColor"/>
</svg>

```
It's a heart :D 
![Heart Shape](https://thepracticaldev.s3.amazonaws.com/i/rn85r1aib34e0mvauynd.png)

##WEBP
WEBP was created by Google in 2010 as an image format for the web. It supports both lossless and lossy compression, supports opacity and is usually smaller than both png and jpg. It's pretty amazing and has [decent browser support](https://caniuse.com/#search=webp) (80% at the time of writing). WEBP should always be used with a fallback option to cover that remaining 20% (you'll learn how to do that in the next part). It will have a huge positive impact on your site though and support is only expected to grow.

##How do you compress
 - If you want to compress just a few static images use https://squoosh.app/. It also lets you play around with different types of compression and see the difference in quality and filesize in real-time! 
 - If you need to compress a lot of images/dynamic images you can use something like [sharp](https://github.com/lovell/sharp) on your backend to compress your image to multiple versions.
 - Alternatively, there are also services like Cloudinary that compress images for you and distribute them over a CDN (which is also usually faster than your server)

##Summary
 - Use SVG for logos/icons etc or anything you want to animate
 - Use WEBP for everything else with either JPG or PNG as a fallback
 - Use JPEG for Photos (as a fallback for webp)
 - Use PNG for logos/illustrations etc when no SVG is available (as a fallback for webp)