Printable Lazy Loading 🖨️
Tags: webdev, html, performance, a11y
Published: 2021-12-16 21:01:35

The past year has been a good one. Well, at least for page speed optimization. With [Firefox support for natively loading images](https://www.ghacks.net/2020/02/15/firefox-75-gets-lazy-loading-support-for-images/), it has never been so easy to defer image loading!

But wait ...

## What about Printing?

[Accessibility](https://www.a11ymatters.com/) and [progressive enhancement](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement) usually go together well with "web performance" (page speed optimization), but **lazy loading** has always been tricky. For a long time, it was not possible without using JavaScript, and if it's done the wrong way, you risk that your website's visitors will not see the images they are supposed to see.

![Source code with lazy loading, the working website, and a printed document with a missing image.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jhfdqdcxayzdyvk3pfy4.png)

[Lazy loading images with accessibility and printer support](https://stackoverflow.com/questions/65378621/lazy-loading-images-with-accessibility-and-printer-support) was still an open issue when [I relaunched my portfolio website](https://dev.to/ingosteinke/creating-a-fast-and-beautiful-portfolio-website-using-html-css-and-eleventy-and-netlify-9f5) last year.

## Understanding the Problem

Due to a [bug in Chrome](https://bugs.chromium.org/p/chromium/issues/detail?id=875403), the first browser to support native lazyloading, images that have not yet been loaded will be missing in the printed page.

### What to use Lazy Loading for?

Benefits of lazy loading: web performance, page speed, load time optimization can be good for user experience and search engine optimization when done in the right way.

### Layout Shift

Layout shift can make users click on the wrong links by accident and make them lose their focus while reading, so it has become a [core web vital in 2021](https://dev.to/ingosteinke/optimizing-speed-and-usability-for-google-s-core-web-vitals-1286).

This problem is caused by the disturbing effect that elements take up more space after being loading completely, thus moving the content below and causing the whole page to shift.

Don't forget to specify the `width` and `height` attributes for every image element, and properly style containing elements to ensure a placeholder that is exactly the same size as the image to be lazily loaded later on. Doing so will prevent layout shift caused by this image or its container element.

How to examine layout shift? developer tools offer to highlight layout shift. In the current Chromium browsers, this option can be found in the "Rendering" tab.

![Screenshot: Chrome developer tools offer to highlight layout shift.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qtttsqcsoq5o1ju2hnc.png)

### "Above the Fold"

Also you don't want to defer loading elements **"above the fold"** which means elements that are visible as soon as you open a website. [The fold](https://en.wikipedia.org/wiki/Above_the_fold), a word dating from printed newspapers, now means the bottom of the initial viewport before scrolling the page.

But you do want to optimize "below the fold" and load images and videos on demand only, otherwise you might make the user load data (which will take time and bandwidth, probably causing costs for the data transfer) that might never be needed at all.

### Unpredictabilities of Responsive Web Design

What is above or below the fold depends on the user's devices. See how [my blog](https://www.open-mind-culture.org/) looks differently on different screens:

![Open mind culture blog on a large screen and on an iphone, held in front of the screen.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/okm3ay4z01vo1havegxd.jpg)

Other aspects to consider: Maybe some images are very important and occur several times on the same website so chances are that they will be viewed sooner or later anyway.  Maybe they have such a small file size that lazy loading will not make much of a difference.

## Native Lazy Loading

Either way, you can control which images to defer and which to load as soon as possible by setting the `loading` attribute.

`loading=lazy` activates deferred loading, while
`loading=eager` is the default without any explicit deferring.

Browser Support

Native lazy loading has first been supported by Google Chrome since Chrome 77 in 2019, and it's currently supported by popular browsers except for the usual suspects (Internet Explorer and Safari).

[![Can I use lazy loading?](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pdjf3jistwx4ot1d2odb.png)](https://caniuse.com/?search=loading)

## Testing

Good news: you don't need to buy an actual printer device, to test your website.

* Print preview and saving as PDF will give you a good idea
* You can emulate media type print in the browser's developer tools:

![Screenshot: emulate media type print in Chrome developer tools](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nxch7mvq7ku5n5141pmw.png)

## Missing Images

Printing a document without images might actually be beneficial and save our users and our environment wasting toner and paper for irrelevant decoration.

As a web developer or content creator, I want to actively decide what to print and what to omit. But using native lazy loading, every single one of the deferred images is missing in print preview.

## Discussion

[Lazy loading images with accessibility and printer support](https://stackoverflow.com/questions/65378621/lazy-loading-images-with-accessibility-and-printer-support), my question on StackOverflow:

[![Preview screenshot of StackOverflow question: Lazy loading images with accessibility and printer support](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wlu3h35xpl04vf0m8kja.png)](https://stackoverflow.com/questions/65378621/lazy-loading-images-with-accessibility-and-printer-support)

I had been "looking for a proper way to implement lazy loading of images without harming printability and accessibility, and without introducing layout shift (content jump), preferably using native `loading=lazy` and a fallback for older browsers".

An elegant solution should be based on valid and complete HTML markup, thus using `<img src`, `srcset`, `sizes`, `width`, `height`, and `loading` attributes instead of using `data-` attributes, like the popular JavaScript libraries [lazysizes](https://github.com/aFarkas/lazysizes) and [vanilla-lazyload](https://github.com/verlok/vanilla-lazyload) do.

My question got two extensive answers (thanks [Graham from INHU](https://dev.to/inhuofficial) for taking the effort) and no official statement from Chromium developers so far.

But [Chrome/Chromium developer Addy Osmani](https://dev.to/addyosmani) [replied to my tweet](https://twitter.com/addyosmani/status/1326633482148216832) by providing a link to [Houssein Djirdeh's solution](https://lazy-load-with-print-ctl1l4wu1.now.sh) (or rather workaround):

>  it implements a custom print button that iterates through all images and sets `loading=eager` prior to calling `print()`.
> Otherwise waiting on [issues 2532: Asynchronous print events to load deferred images](https://github.com/whatwg/html/issues/2532)

[![Preview screenshot from Addy Osmani's tweet quoted above](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/75z3jsw41dgixsh76xmu.png)](https://twitter.com/addyosmani/status/1326633482148216832)

## Conclusion

As both [Wikimedia](https://wikimediafoundation.org)'s [WHATWG issue](https://github.com/whatwg/html/issues/2532) and the [Chrome bug](https://bugs.chromium.org/p/chromium/issues/detail?id=875403) are still open

Follow and join the discussion using the links provided in this article and try to make the proper decision on how to use native lazy loading in your next project.