Optimizing Photos Within a Responsive Design
In the next post in our Sustainable Web Design series, we look at ways to optimize images for better performance and increased sustainability, within responsive design.
Responsive web design has changed the way we make websites. We don’t have to rely on device detection any longer to serve up a separate “mobile” site whenever the server detects what is (probably) a phone or tablet. CSS media queries allow us to serve up a single code base and alter the appearance of a site based on the viewport size of the user’s browser. This means that code can be maintained more easily, and that user experience can be fine-tuned no matter what device a person is using.
But there has been an elephant in the room of responsive web design: performance. A website that looks great on a handheld device is a good start, but if that site loads megabytes upon megabytes of images and bloated JavaScript, it could take ages to load on a device with a cellular connection. Poor page speed is one of the biggest things that can impede visitor conversion, and depending on the user’s phone plan, a bloated site could even cost the user money. In addition, it takes more energy on both the server and client side to load bloated pages. Unless that energy is coming from a renewable source such as wind or solar, poor performance equates to a bigger carbon footprint. So what can we do? Let’s take a look at what often contributes the most to page weight: images.
Images on your site can be displayed in one of two ways: in your CSS as a background image, for decorative purposes; or in your HTML as content, using the tag.
Responsive Background Images: The Easy Part
If a site is being viewed on a smartphone, it’s wasteful to load the same monstrous background image that shows up when the site is viewed on a high-resolution desktop monitor. Luckily, swapping out background images is easy using media queries. You just do something like this:
@media screen and (min-width: 320px) {
.content {
background-image: url(small-image.jpg);
}
}
@media screen and (min-width: 600px) {
.content {
background-image: url(medium-image.jpg);
}
}
@media screen and (min-width: 800px) {
.content {
background-image: url(large-image.jpg);
}
}
You may also consider not loading a background image at all until a width at which it becomes an added value to the user. That will depend on your overall site design.
As long as your media queries use min-width rather than max-width properties, the browser will only download images that are defined in media queries with a min-width that’s less than the width of the browser’s viewport, or display size. A smartphone with a 320px viewport width, like an iPhone, will only load “small-image.jpg” and not “medium-image.jpg” or “large-image.jpg”. This will decrease page load time and bandwidth usage.
Responsive Images in Content: A Real Can of Worms
Great, background images are taken care of. Easy! Let’s move on to images contained within your HTML. Now, you may be thinking: “Media queries eh? I know, I’ll just do this with my HTML…”
<img class="image-small" src="small-photo.jpg" />
<img class="image-medium" src="medium-photo.jpg" />
<img class="image-large" src="large-photo.jpg" />
“And I’ll do this with my CSS…”
@media screen and (min-width: 320px) {
.image-small {
display: block;
}
.image-medium {
display: none;
}
.image-large {
display: none;
}
}
@media screen and (min-width: 600px) {
.image-small {
display: none;
}
.image-medium {
display: block;
}
.image-large {
display: none;
}
}
@media screen and (min-width: 800px) {
.image-small {
display: none;
}
.image-medium {
display: none;
}
.image-large {
display: block;
}
}
“Done! Blog post over!”
Slow down, cowboy. Unfortunately, this approach won’t help. Visually, it will work, but browsers will still download all three images, while only displaying one. It ends up being worse than just having one large image that’s sized down with CSS.
(Tim Kadlec did a thorough test of different methods of hiding and showing images, to see when various browsers downloaded image files. It’s worth a look if you want to know how a specific edge case might work.)
Okay, if CSS can’t affect what assets are downloaded, then what can? How can we make sure that a browser will only download the images it needs to load, and not ones it doesn’t?
We happen to be in an interesting point in time to be asking that question. In the early 2010s, the web development community struggled to find a responsive image solution.
Some attempts use Javascript and cookies, or a combination of cookies and server-side resizing of images, or third-party serving and resizing of images, or even packing sized images as background images defined in media queries within an svg file. But these solutions have many dependencies and variables, and are ultimately still hacks. What we need is a new image markup standard.
A Glimpse Into the Future
I won’t get into the process of how new web standards are implemented, but suffice to say, it’s complicated. And like all things that are political, the process doesn’t always go smoothly. At the moment there are two proposed markup patterns for responsive images:
Each approach works a little bit differently and has its own advantages and drawbacks. This article on A List Apart describes the debate well. At this point, the browser makers seem to prefer srcset
, while the majority of the web developer community prefers <picture>
.
Other helpful advancements that we may see in the future include a new responsive image format, and a standard for bandwidth detection. These are still in very early (even speculative) phases right now, so don’t hold your breath.
Work With What Ya Got
Until a new image markup standard emerges, we have to do what we can. If you’ve put your money on the element being implemented, you can use Picturefill, a JavaScript polyfill for the
element, which will fall back to
if and when it is implemented. Another option is HiSRC, a jQuery plugin that uses Foresight.js to test the end-user’s bandwidth and swaps out src attributes on an image accordingly. Some of the previously mentioned solutions like Adaptive Images may also be sufficient. This article on CSS-Tricks and this article on Smashing Magazine can help you decide which solution is right for you.
Let’s Not Forget Why We’re Doing This
All of these solutions have their issues, even the newly proposed standards. But even if there’s no perfect solution for responsive images yet, a less-than-perfect solution is still better than nothing. We can’t lose sight of our end goal: fast-loading websites that don’t require a lot of bandwidth and processing power.
Aside from choosing a responsive image solution, there are a few other things we can do to save our users from unnecessary image bloat:
- Optimize your image files
- Implement a lazy loading technique, which only loads images once a person has scrolled down to where the images are located on the page
- If you’re comfortable with user agent detection, employ it for your images within an otherwise responsive site, a technique known as RESS
- Just use fewer images!
And don’t forget, this isn’t just for “mobile” users, or users on a slow connection. These kinds of performance optimizations help everyone, regardless of their screen size, bandwidth, or device capabilities. And this is also a component of sustainable web design, which helps the planet.
Digital Carbon Ratings, now in Ecograder.
Understand how your website stacks up against industry carbon averages with this new feature.
Try Ecograder