Lazy loading, or loading content on demand, is the process of identifying resources that are non-blocking to a website and delaying their loading or initialization until the page needs them.
This article outlines the benefits of loading content on demand, how to do it, and when the technique should be applied.
💡 A quick caveat: in providing these tips, we assume all essential performance-related implementations already exist on your website and that, like us, your goal is to optimize page load time and Largest Contentful Paint (LCP) further.
Let’s dive in.
Why is lazy loading important?
You’ve done everything right: content delivery network (CDN) setup, file compression enablement, static JS and CSS file minification, and resource caching. You’ve been sure to follow good coding standards and promote the reusability of components. Now, you’re monitoring your website’s performance and hoping for the best.
But even after all this work, your page still takes too long to load.
You measure your loading time using a performance monitoring tool. As you suspected, it returns a poor score. But the problem is that none of your website resources can be removed—they're all crucial elements of your site in one way or another.
This is when lazy loading comes in.
4 key benefits of lazy loading
Lazy loading has several benefits, but these are 4 of the biggest:
Reducing the initial web page load time by reducing the total size of resources downloaded
Conserving the user's bandwidth, especially keeping in mind mobile data plans on mobile devices
Conserving system resources, as requests to the server are made only when needed
Avoiding unnecessary code execution
And when websites load fast and well, you can experience
Increased conversion rates
More page views
Higher search engine rankings
Lower server bandwidth costs
Smoother usability on different devices
But you might be wondering: don’t I need all the resources included in our website? Is there anything we could load on demand?
Answer: there's almost always something you don't need immediately.
Start by identifying the level of importance of the resources. Some resources might not be ideal to lazy load, such as main JS bundles, main CSS styles, fonts, and analytics packages that need to be available on the initial website load.
When to implement lazy loading
The most common resources to lazy load include
Bundle JS files
Vendor or third-party JS files
CSS files
Images
As your website grows, so does the final bundle of JS and CSS files. To use this technique effectively, you need to split the JS bundles and CSS files.
The traditionally bulky file holding JS, and another hefty file containing CSS, are no longer an option for the modern front-end tech world we live in. Once you’ve completed this critical step, you’re ready to reap the benefits of lazy loading.
🔥 7 scenarios where lazy loading is beneficial
Loading JS bundles that aren't used on the currently viewed page but are used on other pages of the website
Loading JS components and any library backing them up immediately instead of when that component is viewable on the page
Using a third-party JS library which is only required on a specific page. Such libraries can be for ready-made features, JS utility libraries, animations, analytics, or monitoring purposes.
Loading CSS-style files for the entire website rather than loading only the style files needed for the viewable page
Loading a collection of images that aren't visible to the user until the user scrolls to a particular part of the page
Loading of a resource when a specific DOM event has been triggered, such as resize or click
At a specific state within your website, such as after submitting a form and showing a submission success component that might be animation-heavy
Example: how a SaaS website used lazy loading in a React application
Here’s how Hotjar by Contentsquare, used lazy loading to improve its site.
Hotjar by Contentsquare was a Next.js application that relied heavily on the ReactJS library and its available components.
For images, Hotjar by Contentsquare used the Next.js-provided component, which lazy loaded automatically. This meant Hotjar didn’t need to worry about the site suffering from overheads not displaying at that moment in time.
Instead, images loaded automatically and displayed once the scroll position of a specific image reaches the browser's viewport.
The discovery
When analyzing the resources on page load, Webpack Bundle Analyzer helped Hotjar by Contentsquare identify a specific external library that was adding an overhead of 67.3kB on every page refresh.
As you can see below, Webpack Bundle Analyzer’s output reveals lottie.js as one of the large libraries immediately downloaded on the page load.
![[Visual] webpack bundle](http://images.ctfassets.net/gwbpo1m641r7/0OsH9i9RvmsCKRadLAynG/7191793b9417f3cf41511b6bc9237e97/webpack_bundle.png?w=1920&q=100&fit=fill&fm=avif)
Webpack Bundle Analyzer’s output
Hotjar by Contentsquare also discovered this library was only used at the bottom of the page, to render a nice animation once a subset of components was in the viewport.
Lazy loader implementation
The idea was to create a new component (called LazyLoadOnScroll) to wrap other React components. The logic behind it uses a hook that benefits from the browser’s Observer tools, specifically the IntersectionObserver. Any components wrapped with this won’t render, and any underlying external files, libraries, or JS files won’t download.
Once the user starts to scroll and this component is about to come into view, the IntersectionObserver returns a value of 'true', meaning the component is about to intersect the viewport. At this point in time of scrolling, everything begins downloading, and React renders the component accordingly, making it appear to the user as if items are seamlessly being served on demand.
The new files introduced are the following:
useIntersectionObserver: this is the hook responsible for observing the provided component ref via an IntersectionObserver instance to return 'true' or 'false' as to whether the ref has intersected the viewport. It can also be extended by providing additional config props, but our use case required only the most basic implementation. This includes a check to make sure the browser supports IntersectionObserver; otherwise, it will return 'true' to render the content immediately every time.
![[Visual] lazy load Contentsquare](http://images.ctfassets.net/gwbpo1m641r7/6ecJiGo4Ef5Ugb4fyA3LHG/5b6ace3822eafe76eba7e71788bd59d7/lazy_load_3.png?w=1920&q=100&fit=fill&fm=avif)
LazyLoadOnScroll: this is a React functional component that uses the useIntersectionObserver hook. It contains a statement checking whether the hook is being run on a server. If it is on a server, Next.js ‘Server Side Renderer’ will present the page to the client. The hook always returns 'true' so as not to lazy load anything, and the full page is generated for SEO purposes. When this component is initiated, it sets the children to render once the hook returns 'true'. The process occurs once, and the component does nothing else but keep the children in the rendered document.
![[Visual] lazy load contentsquare example](http://images.ctfassets.net/gwbpo1m641r7/27T9w5NGo34fPwKYlmCJJT/a3a2171978780ad5e2f0c4798f9083b9/lazy_load_2.png?w=1920&q=100&fit=fill&fm=avif)
Putting it into practice
Implementing it is as simple as wrapping any component you want to lazy load. Plus, there’s no need to worry about extra overheads on page load.
![[Visual] lazy load examples contentsquare](http://images.ctfassets.net/gwbpo1m641r7/2vpNDhelefTf1P1NMKrUva/a9d6ac894d751d37aeacc0021c69a72a/lazy_load_1.png?w=1920&q=100&fit=fill&fm=avif)
The end result
Hotjar used Chrome's devtool, Lighthouse, to generate a report before and after implementation. Results were fascinating, specifically our Desktop scores.
From an overall score of 87 on performance and an LCP of 1.9 seconds…
![[Visual] speed test Hotjar by Contentsquare](http://images.ctfassets.net/gwbpo1m641r7/778dMg4E2X0BfhDSuJceOi/0f82defb6ad30cf9ca9c3431f5f6ec1d/speed_test_2.png?w=1920&q=100&fit=fill&fm=avif)
…the team managed to go up to an overall score of 93 on performance and an LCP of 1.5 seconds.
![[Visual] speed test Hotjar by Cotentsquare II](http://images.ctfassets.net/gwbpo1m641r7/4aVGTrzZcRH3n4AQlMfTL9/911fec3763e32f348d59f349af6faf73/speed_test_1.png?w=1920&q=100&fit=fill&fm=avif)
![[Visual] Contentsquare's Content Team](http://images.ctfassets.net/gwbpo1m641r7/3IVEUbRzFIoC9mf5EJ2qHY/f25ccd2131dfd63f5c63b5b92cc4ba20/Copy_of_Copy_of_BLOG-icp-8117438.jpeg?w=1920&q=100&fit=fill&fm=avif)
We’re an international team of content experts and writers with a passion for all things customer experience (CX). From best practices to the hottest trends in digital, we’ve got it covered. Explore our guides to learn everything you need to know to create experiences that your customers will love. Happy reading!
![[Visual] Lazy Loading: Why It’s Important And When To Use It](http://images.ctfassets.net/gwbpo1m641r7/4fMHQgDqUHILPCRfWYXmpl/662edd7fbc4a069faf02655b479e83d0/Copy_of_Emotional_Intelligence.png?w=1920&q=100&fit=fill&fm=avif)