Lazy loading images without JavaScript

Posted in Development, HTML and Performance

When you’ve got loads of images on a page, you might not want the browser to fetch them all at once.

Some obvious examples are blog listing pages, or that page where a company introduces you to all of their many employees. If there’s one image per item in the list, there’s probably a lot of images! And with a lot of images comes a lot of requests to the server, lots of downloading, and lots of data allowances being burned through.

There are a few techniques we can use to keep this manageable:

  • pagination (common for search results)
  • infinite scrolling (common on social media)
  • ‘Load more’ buttons (common with e-commerce)

Even then, there can be plenty of images to fetch and display. Maybe the visitor only needs the first few, if they were looking for the latest blog post, or Aaron Aardvarkson in that alphabetically sorted employee list. Of course, they might need to scroll down to find the post/person they came for, so why not defer loading those images until we know they’re going to want them?

Enter lazy loading

Lazy loading has been around for a long time. The image’s src="" attribute contains a placeholder image which is swapped out with JavaScript when the user scrolls close to it. But I’ve never been comfortable with that – what if the script fails and the visitor is left without an image? Not a great experience.

Progressive enhancement is the key, and the HTML-only loading="lazy" attribute is all that’s needed:

<img src="/img/my-great-image.jpg" alt="My alt text" loading="lazy" />

We’re telling browsers that the image should only be fetched when it’s needed:

  • if it’s in view, or nearly in view when the page is loaded
  • if the user scrolls near the image (just before it comes into view)

Browsers that don’t understand the loading="lazy" attribute will still fetch the image, so be careful not to rely too heavily on it, but it’s a nice enhancement for those pages where you would’ve served a bunch of images all at once anyway.

Support across the board isn’t far off. Firefox, Chrome, Edge and Opera have it, and Safari has it behind a flag (from the menu: Develop → Experimental Features → Lazy Image Loading).

Hopefully the more it’s used, the quicker the Safari/Webkit team will be to get the feature baked in as a default. I don’t have any image-heavy listings pages on this website, but I do have case studies that use screenshots and diagrams for illustration, so you’ll find a few choice loading="lazy" attributes over there.

Get them delivered!

If you enjoyed this and want all the latest articles delivered to your inbox every month, pop your email in the form below.

I don’t collect any data on when, where or if people open the emails I send them. Your email will only be used to send you newsletters and will never be passed on. You can unsubscribe at any time.

More posts

Here are a couple more posts for you to enjoy. If that's not enough, have a look at the full list.

  1. Text snippets on Apple devices

    I’ve been using Apple’s built-in Text Replacement instead of TextExpander for a while now. It’s pretty basic, but it’s free and it does the job.

  2. The right way to use break tags in HTML

    Break tags are often misused. I’ll demo some markup patterns to avoid them, and reveal the one and only legitimate use case I can think of.