Three tools to compress your images and make them smaller:
- ImageOptim again. But this one takes a lot of time with PNGs, so if you have many of them to process, you might want to make yourself a cup of coffee while the tool is working.
- ImageAlpha. Much quicker than ImageOptim. It’s my go-to desktop solution for PNGs.
- Optimole. Unsurprisingly, Optimole handles PNG compression as well. Everything happens on autopilot.
📏 Serve images of the correct dimensions
This is perhaps the most crucial aspect of the whole “responsive images” riddle. As we know, there are tens if not hundreds of different screen sizes out there, and we somehow must make sure that our images are going to look great on all of them.
The easy solution? Serve a big image … it can always be scaled down, right? Well, technically, that is correct, but in practice, this will waste a lot of bandwidth and make your site load really slowly on most devices.
A better solution is to scale all images to the correct sizes that are preferable by the most common devices and then serve them accordingly.
As you would expect, you do need different versions of the same image to achieve this.
One of the ways to go about this is to start with your design’s base width and the biggest image size that can be used, and then scale down from there for some common devices and breakpoints.
For example, most websites don’t go above the 1100 px mark for content block width, so you can assume that the max image that can be displayed in that case is 1100 px in width as well.
Then, you can create breakpoints for 800 px and 550 px (common values) to cover tablet and mobile scenarios. While this won’t give you 100% perfect results on all devices, you’re at least optimizing to a reasonable extent and keeping your images under control.
With this behind you, you now must create a handful of different versions of each image that you want to use on your site.
Here’s an example of how to handle the actual display code:
<img src="https://www.codeinwp.com/image.jpg" srcset="image-550.jpg 550w, image-800.jpg 800w, image-1100.jpg 1100w" sizes="(max-width: 1100px) 1100px, 100vw" />
The magic of the
srcset attribute is that the browser looks at what’s in it and then picks the best image based on the device being used.
One more customization that you can see above is the
sizes attribute. This one tells the browser how the image should behave on certain screens. In this scenario, the image is going to be 1100 px when viewed on viewports larger than 1100 px, while on smaller devices it’s going to take up the whole viewport.
This sort of solution makes sure that the image doesn’t take up a whole 3840px-wide 4K screen. However, it will still occupy the entire screen when viewed on mobile.
This effective use of the
sizes attribute is how you make your images truly responsive.
⭐ Pro trick: Go for images that are 10% smaller in dimensions than what’s needed, and then let the browser scale them up. This will save you some additional space and bandwidth. For example, if you require an image that’s 500×500 px, you can scale your image to 450×450 px, and then let the browser scale it up to 500. This does depend on the image, but in most cases, the user won’t notice.
📺 Optimize images for Retina and HiDPI screens
The other end of the image dimension spectrum is about HiDPI-friendly images.
The story is that desktop screens keep getting bigger and bigger, and their pixels keep getting packed more and more densely. It’s not uncommon these days to have a 4K screen packed into a 15-inch laptop. The 4K resolution is 3840×2160 px, so each of those pixels has to be really tiny.
This creates problems for websites. Basically, if your site was defined as 1100 px wide then, under normal conditions, it would only take up roughly 25% of the available screen real estate of a 4K screen. This is not optimal. Luckily, things don’t work like that.
To avoid the issue, those high-res screens act as if they were half the size (I’m oversimplifying, but hear me out). So, instead of your 1100 px wide website occupying a small portion of a HiDPI screen, it gets scaled up to double that, taking up 2200 px and filling the screen much better.
This process allows screens to keep getting sharper and sharper without making everything look tiny in the process.
However, this practice is not without its faults. Chiefly, your images take a huge hit. Text is easy to scale up without losing quality. Fonts are immune to scaling. Images are not. As a direct result, every image that’s not ready for HiDPI screens will look blurred, heavily!
To fix that, you must deliver scaled images for each of the zooming ratios. Here’s some simple code:
<img srcset="img-orig.jpg, img-2x.jpg 2x, img-3x.jpg 3x" src="https://www.codeinwp.com/img-orig.jpg" />
(If the browser doesn’t support
srcset, the standard
src will be used.)
Now, when I say “scaled images,” I actually mean that you should start from the other end. Begin with a huge image (label it 3x), then scale it down and make it smaller (to 2x), and finally make it 1x and use that as the default image.
⌛ Defer image loading
This is simple in principle; all images that are above the fold should be loaded immediately (on page load). Everything else can be deferred for later, and even “lazy loaded.”
Lazy loading is image loading on demand. I.e., images get loaded only a split second before the user needs them – not sooner, not later. And that “not sooner, not later” part is key here.
In an ideal scenario, the image should be loaded just before it gets scrolled into the viewport. Meaning, the user shouldn’t have to see a placeholder before the image appears. If that happens, they might scroll pass the image without it managing to load in time – not a great way to optimize images.
🌐 Deliver images via a CDN
A Content Delivery Network is like a cheat code for site speed. You’re cheating because you’re not as much making your site faster, as you’re telling someone else to take the load and deliver the site’s data to the visitor for you.
👉 We talked about CDNs more in-depth here, check it out.
The TL;DR is that CDNs take advantage of a network of servers that all hold a copy of your site and then deliver it to the visitor from the nearest available location. This is always going to be faster than delivering from your main server.
Image CDNs work pretty much the same, but they focus only on, you’ve guessed it, images.
Most of the time, the operation is seamless from your point of view. All images on your site get replaced by their CDN-hosted versions (meaning that the image URLs change).
- Jetpack has a popular image CDN built right in. You can use it for free, which is great. The main limitation is that it only works with the images in your posts, pages, and your featured images. It doesn’t work for any images that make up your design (parts of the theme, layout, etc.). Those are the images that could really use some CDN-ing.
- Optimole has a CDN built-in as part of the main image optimization feature. This one is not limited to your posts and pages only.
🐌 Serve smaller images to users on slow connections
Not only screen size matters when deciding what type of image the user should see. Probably even more importantly, if they’re on a slow internet connection, they really don’t want to wait 10 seconds for an image to load.
In these scenarios, it’s a lot better idea to downgrade the quality of your images in exchange for load time. Users on slower connections will appreciate that they can see the images at all.
You can make this happen by utilizing the Network Information API. Here’s a cool tutorial on how it all works if you want to implement it by hand.
If you’d prefer it to be handled on autopilot, again, Optimole!
Along the way, I mentioned a number of tools that you can use to make your site’s image delivery more effective. Here’s a summary of those: