In the world of software development, performance is a crucial metric. How can an application serve and execute multiple requests, without sacrificing performance? It is important to note that performance depends on how data is accessed. If an application needs to access heavy amounts of data, this may affect load times, hence performance. This doesn’t stop certain applications from handling large amounts of data without sacrificing the speed at which they relay the data between the client and server.
In this article, we’ll explore two easy techniques for accessing data: lazy loading and error loading. With each method, we’ll see use cases and advantages and also how these techniques can be implemented in a single-page application (SPA) framework such as React.
Lazy loading is a data-accessing technique whereby resources are loaded only when needed. Resources in this case include videos, images, scripts, or components. If you were scrolling on a webpage, for example, an image on that page would only load once you scroll to it.
Lazy loading is a good way of improving user experience and performance because queries made to the server are kept minimal, and the application only focuses on running operations that are needed at that moment.
With eager loading, all resources required for the running of the application are loaded upfront. Once the page initially loads, all images, scripts, and components are fetched from the server.
Eager loading is particularly beneficial in applications where data in one part of the app is required for other parts within the app. This is common in dashboard applications.
Lazy loading | Eager loading |
---|---|
Loads data only when it is accessed for the first time | Loads all related data at the initial load time |
Results in more database queries, as each related data access triggers a fetch from the database | Results in fewer database queries, as all related data access is fetched upfront |
Uses less memory, as data is accessed only when it is needed | May increase memory usage as all data is loaded upfront |
Code is more complex, as you need to handle cases where additional resources are to be loaded from the database | Code is simplified here, as there is no need to explicitly define any edge cases |
Provides more control, allowing you to decide when to load data, which can be beneficial in scenarios with conditional data access | Offers less control over when data is being fetched, because all data resources are being fetched at once |
Better used in scenarios where data is rarely accessed and is needed only at the time when it should be loaded | Used in scenarios where data is continuously accessed and is always needed |
Single-page application (SPA) frameworks like React have default methods of implementing lazy and eager loading. By using Suspense
and the React.lazy
function in React, we can see how to load a component at will, by clicking a button.
Say we have a component that we only need to use later in our application. We’ll implement this as a component that is loaded at the click of a button. Let’s call the component MyLazyComponent
:
const MyLazyComponent = () => { return ( <div> <p>Look, I am the lazy component that is loaded after a button click</p> </div> ) } export default MyLazyComponent
Now that we have the component to be lazily loaded, let’s see how React implements lazy loading through its inbuilt React.lazy
function:
import React, { Suspense, useState } from "react" const LazyComponent = React.lazy(() => import('./MyLazyComponent')) function App() { const [showComponent, setShowComponent] = useState(false) return ( <> <h1>Lazy component example</h1> <button onClick={() => setShowComponent(true)}>Load Component</button> <Suspense fallback={<div>Loading component...</div>}> {showComponent && <LazyComponent/>} </Suspense> </> ); } export default App
In our App.jsx
file, we instantiate a LazyComponent
variable, which uses the React.lazy()
function to dynamically call the MyLazyComponent
we created before. We have a showComponent
state that is initialized to false and is set to true when the button is clicked. Once the state of showComponent
is set to true, the MyLazyComponent
is then loaded onto the page. The built-in Suspense
component provides a fallback UI for when the MyLazyComponent
is in the process of loading.
With the code as is, we can’t see the effect of the fallback UI because the lazy-loaded component is loaded too fast. Let’s simulate a delay in loading the lazy component. By using a promise, we can use the setTimeout
function to induce a two-second delay. We use a promise here because we are working with a dynamic import:
const LazyComponent = React.lazy( () => new Promise((resolve) => { setTimeout(() => resolve(import("./MyLazyComponent")), 2000); }) );
Running the code with the changes above, you can now see that the fallback UI takes effect just as the lazy component is loaded and displayed on the page:
Something interesting to note, however, is that even without the React.lazy
function, we are able to run and see the same results. This defeats the purpose of lazy loading, however, because the component is still being loaded in the background. React.lazy
is essential because it allows us to dynamically import a component and use it only when needed, without including it in the initial application bundle. This is the whole point of lazy loading. Without React.lazy
, MyLazyComponent
is still included in the initial application bundle.
Eager loading is the default behavior for loading components in React and can be implemented through useEffect
Hooks, or normal component imports. If we had to refactor our code above to demonstrate eager loading, we’d do so as follows.
We have the MyLazyComponent
being refactored to MyEagerComponent
:
const MyEagerComponent = () => { return ( <div> <p>I am an eager-loaded component, hello.</p> </div> ) } export default MyEagerComponent
And as for our App.jsx
:
import MyEagerComponent from "./MyEagerComponent"; function App() { return ( <> <h1>Eager component example</h1> <MyEagerComponent/> </> ); } export default App
You can see that no additional code is required to load the above component eagerly. Running this app would immediately load the eager component onto the page.
In this article, we explored eager and lazy loading in detail, covering their benefits and differences. We also implemented both lazy and eager loading in a single-page application like React using only components.
These techniques are essential in optimizing the performance of web applications. Lazy loading helps enhance user experience by reducing initial load times and conserving bandwidth, making it ideal for infrequently accessed data. Eager loading, on the other hand, ensures data consistency and simplifies code, particularly in cases where data is required across different parts of the application.
By choosing the right loading strategy, you can significantly improve the responsiveness and performance of your application, ultimately creating a more seamless experience for users.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowDeno is a popular JavaScript runtime, and it recently launched version 2.0 with several new features, bug fixes, and improvements […]
Generate OpenAPI API clients in Angular to speed up frontend development, reduce errors, and ensure consistency with this hands-on guide.
Making carousels can be time-consuming, but it doesn’t have to be. Learn how to use React Snap Carousel to simplify the process.
Consider using a React form library to mitigate the challenges of building and managing forms and surveys.