This content originally appeared on DEV Community and was authored by Rob O'Leary
Recently, I was asked if I would be interested in writing an article about responsive images by an editor. The editor was looking for specific advice for experienced developers about the topic. I said no, because I think giving cut-and-dry advice on a topic like this is difficult, and it can easily be misleading if you try to distill it down too much. You need cover the ground properly, so an article series would be more suitable.
There is a 10-part series by Jason Grigsby from 2015 called Responsive Images 101, which provided a thorough tutorial on responsive images, but now it is dated in some respects. Also, Jason wrote an article in 2013 called 8 Guidelines and 1 Rule for Responsive Images that gives more practical advice. I haven't seen a worthy up-to-date predecessor to these articles. Even MDN's guide to responsive images defers to Jason's 2015 article on background images and media queries!
Putting images on the web is not just about making them responsive, there are other considerations. Also, there are changes in this space, which have led to some people to christen today as the beginning of the 'new responsive era'. It's early days on that, so I wouldn't get carried away. What I would say is that things are convoluted now, and we should be looking for a simpler way. There isn't a good set of guidelines for dealing with images in a holistic manner. If you know of any, let me know!
Today, I'd like to discuss some of these issues, and provide some of that missing guidance.
Where doth the difficulty lie?
There are a lot of different considerations with images. You bump into a heap of questions when you're using images such as:
- What's the difference between the image formats? Which should I use and when? What is the browser support like now?
- How do I load images in the most performant manner? Should I preload some images? Should I use lazy loading everywhere? Do I need to use JavaScript for lazy loading? What about that new
content-visibility
property? - What about optimization? What sizes do I use? How do I automate the process? Addy Osmani wrote a whole book on image optimization recently.
- What should I do to make images accessible? Do I use an
alt
attribute on all images? - What do I do with background images? Can I make them responsive?
Chris Coyier also discussed this topic in his recent article Images are hard and said:
Putting images on websites is incredibly simple, yes? Actually, yes, it is. You use
<img>
and link it to a valid source in thesrc
attribute and you’re done. Except that there are (counts fingers) 927 things you could (and some you really should) do that often go overlooked.
Chris goes on to list approximately 20 of these things. There are some bits that come to my mind also that Chris did not mention. I'm not going to make a complete list. It's too much.
It makes me sad that things are like this. There have been improvements in some areas, better tooling is available to cover some of it, but some of it is impractical. I imagine it would feel overwhelming for someone who wants to build a website who is not a web developer but would like to; or a beginner who wants to do things the "right way". We should reassure people that it is OK to just use an <img>
with one appropriately sized image when you are starting out. Your website will work fine. You are breaking no laws. You can learn more and improve on this later. As I discuss later, many of us are pretty loose with how we use images anyway, so he who has not sinned should cast the first stone!
In particular, I say this because it seems to me that that there is more pressure to make everything fast now. Web performance is being hyped up. People are talking more about Lighthouse scores. The marketing guys are linking improvements in performance to revenue gains. And there is the spectre of SEO-reaper lurking. ? SEO rankings are inexplicably being linked to performance now through Google's core web vital metrics.
But, but...I just want to build a small, fan site for BTS! ? Maybe that's why some people prefer to build discord bots instead of websites now.
For me, there isn't a cohesive and clear message on how to do things well. It's an accumulation of stuff that is not synthesized. I think it's important to look at what people are actually doing, rather than what people are saying or suggesting to cut through the rhetoric.
Rereading Jason's article on guidelines from 2013, he says:
No one knows what the future of responsive images holds. A few years from now, we will probably look back on the hacks we’re using and laugh at our naivety.
What do you think? ?
I'm still waiting for holographic personal devices.
How are images really used on the web
Let's look at the Web Almanac to see what is really happening. The Web Almanac is an annual report which "combines the raw stats and trends of the HTTP Archive with the expertise of the web community." Let's look at last year's report with regard to images and performance.
In 2020, the median page weighted approximately 2 MB for desktop and 1.9 MB for mobile, and a shocking 7.4 MB for desktop and 6.7 MB for mobile at the 90th percentile.
The median page weight contains approxmiately 1 MB of images and approxmiately 400 KB of JavaScript.
This is why people point at images as the lowest hanging fruit for reducing page weight. Images are still the most requested type of resource, though JavaScript is closing in!
The thing is it's not just the size of the resources. It's the amount of requested resources. This is the distribution of requests by content type.
The numbers seem bonkers to me. It is common to have 29 images on 1 page! The number of requests on desktop for the media page is the same as last year (74), yet the page weight has increased by 122 KB. Pages are getting bigger.
In terms of performance, it is hard to summarise. This is the most succinct summary directly from the report:
On the surface, we have seen optimistic signals about the new Core Web Vitals performance metrics. At least half of the experiences are good across both desktop and mobile devices, if we don’t narrow down to consistently poor experiences on slower networks for Largest Contentful Paint. While the newer metrics might suggest that there’s an ongoing uptake in addressing performance issues, the lack of significant improvements in First Contentful Paint and Time to First Byte is sobering. Here the same network types are most disadvantaged as with Largest Contentful Paint, as well as fast connections and desktop devices. The Performance Score also portrays a decline in speed (or perhaps, a more accurate portrayal than what we measured in the past).
What the data shows us, is that we must keep investing in improving performance for scenarios (such as slower connectivity) that we often don’t experience due to multiple aspects of our privilege (middle to high-income countries, high pay and new, capable devices). It also highlights that there’s still plenty of work to be done in the areas of speeding up initial paints (LCP and FCP) and asset delivery (TTFB).
Let's just say there is room for improvement! ?
What would you recommend?
Do the basic things well.
1) Ship less images
Ship less images! Don't serve 29 images for your average webpage. Show restraint, be selective.
This made me think of this quote from Dickens:
Subdue your appetites, my dears, and you've conquered human nature.
2) Inline SVG icons
Pasting SVG icons into your HTML will reduce the amount of requests. In the age of static site generators and web components, it is easier to do this in one place and avoid duplication.
3) Use a rule-of-thumb to set the maximum image resolution for your images
You can pick the maximum image size for your page based on its content. For example, if you have a blog and the maximum width of your blog post is 700px, then serve images with a maximum width of 1400px. This will cover high-resolution screens with 2x pixel density. Jake Archibald mentions this as the "lazy way" in his article Halve the size of images by optimizing for high density displays.
4) Provide alternative text
For the sake of accessibility, give a text alternative for an image in the alt
attribute. You should add alt text to most images, unless it is considered decorative. Eric Bailey discusses when you can skip altnerative text in the article - Your Image Is Probably Not Decorative. Spoiler altert: it's not that often.
5) Stick to using one image format with img
if you are inexperienced
For a beginner, I would suggest sticking with a single image format with <img>
. You don't need to learn a static site generator or JavaScript to get started making websites (but it will make it easier in the longer-run). Use JPEG for photos, and use either a PNG or SVG (preferably) for more graphical images such as icons and diagrams. Maybe next year, you can start using WEBP instead of JPEG and PNG. At the moment, WEBP is only partially supported in Safari.
If I follow this recommendation for this page, I use 8 images in the article totaling 169.5 KB. I did run 2 images through squoosh to reduce their size. That's already quite good.
6) Set dimensions for images to reduce layout shifts
Define the dimensions of images through the width
and height
attributes, or the aspect-ratio
property. This will prevent parts of your page moving around when an image loads. This is called cumulative layout shift (CLS) and is one of Google's core web vitals metrics. I prefer to use aspect-ratio
, but it has only just made it to safari. So, now it is in all major browsers, but keep this in mind if browser support is an issue for you.
If you want to learn more about the ins-and-outs of this, you can read the article - Setting Height And Width On Images Is Important Again. It's a 17 min read, yowzer! ?
7) Lazy load images below the fold
For any images below the fold, by below the fold I mean any image that would not be seen when the page is loaded, you can lazy load these images. This will defer loading of images that are off-screen until the user scrolls near them . You can do this by adding this attribute loading="lazy"
to <img>
. This attribute is supported in 74.71% of browsers now, but looking at the most recent data (Jan - Jun 2021) on the HTTP Archive, it is used by just 17% of websites. If I add lazy-loading to this page, only the main image is loaded which is 1.2 KB (images in the page header are always loaded i.e. the logo).
8) Learn the basics of SVG and use SVG for graphical images as often as you can
I would recommend that you learn the basics of SVG. Using SVG instead of PNG is an easy win. Since SVG is a text-based vector format, files can be very small. The main image for this article is a SVG and is 1.2 KB. SVGs can scale up and down without any loss of quality. Effectively, you can have 1 image that looks good on any screen.
By Yug et al. from Wikimedia Commons CC BY-SA 2.59) Optimize your images
You can use a web app like tinypng or squoosh to resize and reduce the file size of your images. If you don't use a lot of images, then this is a shorter process! We will discuss automation of this process in the next section.
That's already a lot! If you do this much, you will be ahead of the median website. Test your website in your favourite audting tool (such as Webpagetest or Lighthouse) to see where you're at.
Look at what browsers you need to support to see if you need to polyfill the loading
attribute.
Beyond this, you are getting into more technical territory, but through automation you can take some of the work off your plate.
The extra yards and automation
The next biggest win is to use different versions of images for different screen sizes (resolution switching), and next-gen formats for browsers that support them. You can choose to do-it-yourself or use an Image CDN.
If you have a small website, a manual process is manageable. Just find a GUI app or command-line tool, whatever you are comfortable with, one that will give do bulk resizing and optimization of your images for you. You just want to point to a folder and have it spit out all of the alternative versions for you. You can add the markup to your page yourself, albeit this can become a bit tedious. You can automate the insertion of this markup with some tools.
If you use a static-site generator or a backend platform like Wordpress, there are integrated options to do this for you such as:
- There is Eleventy Image, which is made for Eleventy, but can be used outside of Eleventy also.
- Nuxt (related to Vue) has nuxt/image.
- Gatsby (related to React) has gatsby-plugin-image.
- Wordpress has plugins such as Jetpack.
To use these plugins, some JavaScript may be required. You could muddle through with Eleventy Image without knowing that much JavaScript. It only makes sense to venture into Nuxt if you already know Vue, and Gatsby if you already know React. It's just to demonstrate that this is something that platform/frameworks are treating as an important concern now, which is good.
What about background images?
Background images are specified in CSS with background-image
.
For now, it's probably best to stick with media queries if you want to swap out background images for different screen resolutions.
There is image-set()
which can take multiple resolutions of an image and let the browser make the best decision about which one to use. It is not quite ready for prime-time yet, there are caveats. If you want to explore this further, you can read this article - Using Performant Next-Gen Images in CSS with image-set.
I would think you're in an excellent state if you have done this much. Of course, there are other optimizations you can do. You have to draw a line somewhere. Test your website out and see if more is necessary.
What about the new responsive era?
I don't know. I prefer to focus on today!
Conclusion
This was meant to be a quick article! I hope I shed some light on a few bits and bobs with regard to images on the web. I just wanted to share some observations and point out some steps you take to use images with an appreciation for performance without feeling overwhelmed. Building websites shouldnt feel like spinning plates! Happy coding!
Image Attribution
The featured distribution graphs are courtesy of the HTTPArchive with rights reserved under a Apache License 2.0.
This content originally appeared on DEV Community and was authored by Rob O'Leary
Rob O'Leary | Sciencx (2021-07-29T14:52:11+00:00) Images are hard. Is there a simpler, more pragmatic approach?. Retrieved from https://www.scien.cx/2021/07/29/images-are-hard-is-there-a-simpler-more-pragmatic-approach/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.