Skip to main content

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.


If you enjoyed reading this and want a monthly roundup of my articles delivered to your inbox, just enter your email 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. Using Pandoc to convert Markdown to Jira’s Textile in Sublime Text

    It’s a real pain that Jira’s plain text input isn’t Markdown. Here’s how to I write in Markdown and export to Jira’s version of Textile.

  2. Apple dials back the Safari 15 for macOS redesign

    The ultra-condensed tab bar in the up-coming Safari for macOS has been reverted in the betas; it’s now just an option in Safari’s Preferences.