On this page
Plane on the sky

Improved lazy loading for image, video, and audio

Improve lazy loading of media by not fetching the resource when it's in the viewport for at least 1 second. Automatically pause playing media when not visible.

Lazy loading is a strategy for identifying non-blocking (non-critical) resources and loading them only when needed. Typically happens in some user interactions such as scrolling or navigation. However, one scenario hasn’t been covered by the native loading="lazy" feature: the ability to control fetching delay. Let’s dive into it.

Optimizing lazy loading for images, videos, and audio: Best practices and strategies

Today’s day it’s easy – add loading="lazy" attribute to the image. Audio and video don’t have a direct method of lazy loading, but the attribute preload can be used with its respective values: none, metadata, and auto to limit data to download.

While this looks like a good solution then it seems that we could improve that even further.

What, if image, video, or audio can be fetched not only when they appear in the viewport, but also with a delay?

The reason is that the user may scroll up, down, left, and right so fast that some resources that the user skips don’t have to be loaded immediately.

Here is an example of 3 different scenarios of how users interact with the page and what’s happening with images, audio, or videos:

3 phones with 3 pictures on each: 1. All pictures are loaded. 2. Images outside the visible area are not loaded. 3. The user quickly scrolls the page up, down.
  1. In scenario 1 all images are loaded regardless of using loading="lazy" attribute.
  2. In scenario 2 images that are visible to the user are downloaded. Other images aren’t downloaded.
  3. In scenario 3 the user quickly scrolls up, and down, and that indicates the user is not interested in seeing those images. Hence ideally would be to skip loading them.

So, from our observations, we have noticed:

  1. When the user scrolls the content quickly then it indicates the user intentionally skips some part. So, not all images that appear in the viewport must always be fetched. Regardless of using the attribute loading="lazy".
  2. Video or audio can use the attribute preload with the value metadata or none. However, that tells the browser only what could be preloaded, but that doesn’t cover the scenario: Hey, load only when it appears in the viewport for more than 1 second.

    You may have so many videos or audio on one long page (e.g. timeline) that even using preload="metadata" will still trigger download metadata, sometimes quite large, for all resources.

The solution: Streamlining lazy loading for enhanced user experience

The solution for that is to use Intersection Observer API and once the image, audio, or video appears in the viewport wait 1 second before initiating fetching. See the implementation of improved lazy loading on Github.

Additionally, when the audio or video isn’t in the viewport, you may want to pause playing it. It is very useful when you play muted video in the background, for example.

Demo: Visual example of improved lazy loading in action

See the action of improved lazy loading for image, audio, and video in a real demo.

Performance enhancement with lazy loading: Does it really work?

Definitely yes. Summary in a few points:

  1. It improves loading and rendering performance because the browser doesn’t have to fetch all resources at once.
  2. It saves the bandwidth for your user because less data is required to get from the server.
  3. It should impact the SEO because faster loading and rendering means a better user experience. Great performance is a major ranking factor.
  4. Use a placeholder for each image so the user sees it instead of a blank space. It can be an image base64 encoded, for example.

See also the article 8 tips to speed up image loading.

Related posts


Leave a Reply

Real-user monitoring for Accessibility, Performance, Security, SEO & Errors (SiteLint)