Back to all blogposts

Lazy loading – a simple method to speed up loading time and improve website’s UX

Tomasz Kajtoch

Tomasz Kajtoch

Senior Frontend Developer

What’s Lazy loading? It’s a design pattern that can effectively speed up your websites and applications by deferring loading non-critical resources. Instead of loading content at page load, it is being loaded when needed (that’s why some people call lazy loading “on-demand loading”). Thanks to this simple principle of operation, it can be used in almost every kind of web and mobile apps. In this article, I’m gonna tell you how to implement lazy loading images in your projects.

Browsers try their best to optimize loading pipeline by analyzing DOM tree and determining what can they skip while doing the initial render. They use various techniques to achieve that – for example by ignoring elements that have display: none;. However, it’s often unpredictable, especially with Single-Page-Applications where JavaScript generates DOM elements. That’s the main reason why we need to help browsers to tell what users see first.

Note: If you’re looking for the new Lazy Loading HTML loading attribute for img and iframe tags introduced in recent Chrome versions, make sure to check out my next article: “The new native lazy loading for images and iframes in Chromium-based browsers”! 😁

"The new native lazy loading for images and iframes in Chromium-based browsers

Introducing the loading problem

Modern websites are full of various images and videos, making them more appealing to a user. It’s an important part – visual elements attract attention from the first time the user loads a web page and can tell more and much quicker than blocks of text. While being an excellent method of telling a story, graphic visuals weight a lot, and each of them increases page load time. Basing on HTTPArchive report, at the 90th percentile sites send on average 6.9MB of data, where over 4.7MB of that are just images. The conclusion is simple, the heavier the web page is, the slower the loading.

My workmates have already written on improving applications’ accessibility for disabled users and how to cut down flashy effects to make animations more user-friendy. Unfortunately, sometimes getting rid of media from a web page is often a no-go, and there’s a need for another solution to this problem.

Luckily, lazy loading is a way to go – it lowers the load time, allows showing the content quicker, but it doesn’t require to make any cuts in graphics.

Principle of operation

Lazy Loading defers fetching non-critical resources at page load time and waits until they are needed. In the context of images and videos, the term “non-critical” refers to being off-screen so a user won’t notice them missing without scrolling. Then, every user interaction event – especially screen scrolling – should trigger a recalculation process to determine whether any of the Lazily Loaded resources should begin to load. In shorts, the user scrolls down and image loading starts. 

Thanks to this, a browser can focus on loading page content and necessary resources first, shortening the overall time needed to display a requested page, hence improving user experience. Moreover, a shorter page loading time helps increasing search engine rank!

I’m sure you’ve seen this lazy loading image effect work multiple times on both small and large websites. You can find “lazy images” on Google Images, Facebook, Medium, as well as simple, personal pages. Let’s look at this lazy loading example:

lazy loading placeholders example

Read more: Honey, I shrunk the node_modules! …and improved app’s performance in the process

Implementation of lazy loading

Implementing Lazy Loading is pretty straightforward and comes down to listening to a page scroll and checking whether to load new resources. If you wrote a code that listens to scroll events in the past, you probably already know that besides listening to scroll event, you should also handle resizeand orientationchangeevents. Surprise, surprise – it’s not required anymore! All thanks to built-in IntersectionObserver that does all the work internally and has better performance in general.

Keep in mind that older browsers don’t support IntersectionObserver, and you might want to use a polyfill or stick to the old-way implementation with the aforementioned events.

React Component

Note: Lazy Loading in the context of this article is not equal to dynamic imports nor React.lazy().

While you could use the plain JavaScript implementation shown below, implementing Lazy Loading on React layer gives you more flexibility, and I recommend using this one.

This code gives you the LazyImage component that takes src property equivalent to img attribute of the same name. At first render, the imgelement has srcattribute set to the placeholder inlined URI. When mounting, it’ll begin to observe the rendered img element until it becomes intersecting.

The important part is to use one IntersectionObserver globally without creating a new one for each component instance. That’ll help performance and memory usage.

For inspiration and production-ready code, check out `react-lazyload` library.

Implementation of lazy loading in JavaScript

Resource Placeholders

To avoid a situation where resource begins to show up on-screen, but it’s not yet fully loaded, pages often use placeholders to temporarily replace the real content. There’s no single way how to implement them or how they should look. However, the most popular ones are:

Dominant Colour Fill

This simple placeholder technique uses a pre-calculated dominant colour value that’ll fill image or video area until it’s loaded. It requires calculating the colour value on the server-side. This way, a browser doesn’t need to make any additional requests. You can find this method being used on Google Images and Facebook.

lazy loading placeholders example dominant colour fill

Low-Quality Image Placeholders (LQIP)

A step-up in the game of placeholders. As the name suggests, this placeholder is significantly processed and compressed version of an input image. The usual way to go is to scale down images, so the wide side has 16px, and save them in a format that has small enough file headers:

lazy loading placeholders example low quality image

In order to prevent making any additional requests, inline the placeholder image URI.

HTML5 Video Placeholder Image

HTML5 video tag supports defining poster attribute that allows displaying a custom image at the time of loading video file. When in pair with preload="none" attribute, it’ll prevent browsers from downloading any video data before clicking the play button. Make placeholders creative, and they will surely keep users’ attention. 🙂

Benefits of lazy loading 

Lazy loading can introduce many benefits, not only for the users but also for website owners too:

  • lowers costs of server infrastructure,
  • improves loading time, 
  • makes the overall user experience much better,
  • decreases network activity by waiting for the user to have lazily loaded elements in the viewport,
  • cuts down hardware resources required to otherwise process additional requests.

To wrap things up, let’s take a look at some new lazy loading developments.

Lazy loading HTML attribute proposal

Chrome 76 introduced a new loading attribute for imgand iframe tags that allow lazy loading of the resources without writing any additional JS code. The browser support is very limited, but if you want to learn more, I’ll discuss this feature in my next article about the new native lazy loading for images and iframes in Chromium-based browsers!

Read more: What’s the difference between UX and UI design in software development?

State of Frontend 2024

👨‍💻 Help the Frontend community! Answer the State of Frontend 2024 global survey. Takes less than 10 mins.

I want to help

The Software House is promoting EU projects and driving innovation with the support of EU funds

What would you like to do?

    Your personal data will be processed in order to handle your question, and their administrator will be The Software House sp. z o.o. with its registered office in Gliwice. Other information regarding the processing of personal data, including information on your rights, can be found in our Privacy Policy.

    This site is protected by reCAPTCHA and the Google
    Privacy Policy and Terms of Service apply.

    We regard the TSH team as co-founders in our business. The entire team from The Software House has invested an incredible amount of time to truly understand our business, our users and their needs.

    Eyass Shakrah

    Co-Founder of Pet Media Group


    Thank you for your inquiry!

    We'll be back to you shortly to discuss your needs in more detail.