Lazy Loading in React
Overview
The technique of utilizing carefully monitored experiments to raise a web application's performance is known as web optimization. An optimization method for webpages or web applications in React is called lazy loading. Because it only loads content that viewers can see on their screens, it is also known as on-demand loading. Let's examine more closely how we can use the concept of lazy loading in a React application.
What is Lazy Loading?
Lazy loading is a design pattern used to optimize web and mobile apps. You can reduce the initial load time by allowing portions of your application to load only when necessary. The idea behind lazy loading is simple and clear, to initialize the elements critical to the user interface first, then silently render non-critical items. For instance, you could initially load the parts and modules needed for user registration and login. The remaining components can then be loaded based on user navigation.
Likely, you're not viewing all of the content on a website or app when you use it. You might never need some components depending on how you use the app and navigate, and loading unnecessary items use up time and computing resources. Hence, you can render elements only when they are needed, increasing the efficiency of your app and the user experience.
Lazy loading may not make a significant difference for small-scale applications. But by making the initial loading time less, it has a significant effect on large-scale applications. The ultimate result is an improvement in the application's usability and user experience.
Advantages of Lazy Loading
- Reduces initial load time :
A webpage can load more quickly by using lazy loading to lighten the page. Lazy loading reduces the bundle size to speed up initial loading. - Bandwidth conservation :
By only delivering content to users when they specifically request it, lazy loading saves bandwidth. Enhances application performance when there is limited bandwidth. Lazy loading reduces network activity by waiting until the user has viewport elements that have been lazily loaded. - System resource conservation :
Because only some of the images, JavaScript, and other code need to be rendered or executed, lazy loading saves both server and client resources. Lazy loading reduces browser workload as unnecessary code execution is avoided. - On-demand loading :
optimizes the delivery of content by using less time and memory. Because only the necessary portion of the website is loaded first, less time is required, and the remainder of the section loads afterward, conserving storage. As a result, the user's experience is improved because the required content is delivered quickly. - Cost Effective :
From the perspective of business executives(Owners of websites), It is a cost-effective strategy since it maximizes the use of available time and space resources. It reduces the amount of hardware needed to process additional requests. - Faster page load :
In all other respects, websites with smaller file sizes load more quickly. A website loads more quickly when it starts smaller than its original loading all at once, mainly due to lazy loading. Improved user experience, higher conversion rates, and better SEO are just a few advantages of a fast website. - No unnecessary content :
Consider a scenario in which a page loads several images below the fold, but the user leaves the page before scrolling down. The bandwidth used to deliver the images in this situation, as well as the time the browser took to request and render the images, were essentially wasted. However, lazy loading makes sure that these images only load when they are required. Because less bandwidth is used, this saves time and processing power as well as possibly saving money for the website owner.
How to Use Lazy Loading in React?
React has two features, React.lazy() and React.Suspense, that make it very simple to apply code splitting and lazy loading to React components.
It is possible to render a dynamic import as a regular component using the React.lazy() function. A key component of lazy loading is code-splitting, which is accomplished through dynamic imports. React.lazy(), a core feature of React 16.6, eliminates the need for third-party libraries like react-loadable.
You can specify the loading indicator with React.Suspense if the components in the tree below it have not yet been rendered.
How to Use React.lazy() and React.Suspense?
React.lazy()
Components that are loaded using dynamic import() and rendered like regular components can be easily made using React.lazy(). When the component is rendered, the bundle containing it loads automatically as a result.
A function that must return a promise by calling import() to load the component is passed as an argument to React.lazy(). The resolved promise that is returned points to a module that has the React component as its default export.
Here is a code snippet importing a component without the use of the React.lazy() function :
Here is a code snippet explaining the use of the React.lazy() function :
In the above code, the AboutScreenComponent has been imported with the use of React.lazy(). The React.lazy() has been given a function that imports the AboutScreenComponent and returns a promise.
React.Suspense
When a component is created using React.lazy(), it is only loaded for rendering purposes. As a result, you should show some kind of placeholder content, like a loading indicator, while the lazy component is loading. React.Suspense was created specifically to address this need.
A component for wrapping lazy components is called React.Suspense. A single Suspense component can wrap up several lazy components at various hierarchy levels.
While all the lazy components are getting loaded, the Suspense component accepts a fallback prop that accepts the React elements you want to be rendered as placeholder content.
As an illustration, you can use the fallback prop to pass the waiting or loading message, and it will be shown until the wrapped lazy component is rendered.
In the above code, the AboutScreenComponent has been imported with the help of the React.lazy() function. The lazy-loaded component has been wrapped inside the Suspense, and the fallback has been assigned a div containing the Please wait message. While the AboutScreenComponent is loaded the message will be shown on the screen.
As you can see, to create a lazy-loading component in React, you must make use of both React.lazy() and React.Suspense. Anyone with a basic understanding of React can use these features because they are simple to use.
However, the React.lazy() function's promise rejections could occasionally cause you problems. You must build a React error boundary component and use it to enclose the Suspense components to avoid such circumstances.
With the aid of the React.lazy() function, the AboutScreenComponent has been imported in the code above. The fallback has been given a div with the message Please wait, and the lazy-loaded component has been enclosed inside the suspense. The suspense is now enclosed in an ErrorBoundary to handle any promise error. The message will be shown up on the screen while the AboutScreenComponent loads.
The suspense component can contain several lazy components :
Route-based Lazy Loading in React
You may accomplish route-based code-splitting without relying on an external package by using React.lazy() and React.Suspense. Your app's route components can easily be changed to lazy components, and then you may wrap each route with a suspense component.
The route-based code splitting using the Reach Router library.
Server-side Code-splitting in React
Suspense and React.lazy() are not currently accessible for server-side rendering. You should continue to utilize react-loadable for server-side code-splitting.
Route-based code-splitting, which involves using dynamic import() too lazy load route components, is one method for dividing the code of React components. Utilizing the dynamic import() syntax, react-loadable offers a higher-order component(HOC) for loading React components with promises.
Take into account the following React component, MyComponent :
Until MyComponent is rendered in this case, the OtherComponent is not necessary. However, because we are statically importing OtherComponent, it is combined with MyComponent.
The code can be divided into different bundles by using react-loadable to delay loading OtherComponent until MyComponent is rendered.
The OtherComponent is lazily loaded with react-loadable as shown here :
The component is assigned to the options object's loader property after being imported using the dynamic import() syntax.
The react-loadable framework's loading property is used to specify a fallback component that will be rendered while the primary component loads.
Lazy Loading Best Practices
When using lazy loading, keep the following recommendations in mind :
- Only use lazy loading in code when it's unnecessary for a website or web app's initial functionality or features.
- Use lazy loading only for elements that are below the fold or outside the user's initial viewport.
- Before adding images that are lazy-loaded to the DOM, decode them asynchronously using JavaScript's decode() method.
- Set appropriate error boundaries to handle any errors that may occur if the lazy loading of the components fails.
- For users who disable JavaScript in their browsers or in circumstances where JavaScript is not available, provide a noscript alternative for the components that are to be lazy-loaded.
Error Handling for React.lazy()
As was already explained, while using React lazy, the import() function produces a promise(). Several factors, including network failure, file not found issues, file path errors, and others, can cause this promise to be refused.
When a lazy-loaded component doesn't load, you should surround it with an error border as illustrated below to maintain or enhance the user experience :
Explanation :
Error Boundaries can be used to manage recovery, handle errors, and present a pleasant user experience. As demonstrated in the code example above, to display an error status when there is a network error, a file not found error, or a file path error, Error Boundaries can be placed anyplace above a lazy component.
Conclusion
- Lazy loading is a design pattern used to optimize web and mobile apps.
- The idea behind lazy loading is simple and clear, to initialize the elements critical to the user interface first, then silently render non-critical items.
- Lazy loading reduces the initial render time, and by only delivering content to users when they specifically request it, lazy loading saves bandwidth.
- Lazy loading saves both server and client resources as only some of the images, JavaScript, and other code need to be rendered.
- Components that are loaded using dynamic import() and rendered like regular components can be easily made using React.lazy().
- A component for wrapping lazy components is called React.Suspense and it can wrap up several lazy components at various hierarchy levels.
- React.Suspense and React.lazy() are not currently accessible for server-side rendering.
- Route-based code-splitting, which involves using dynamic import() too lazy load route components, is one method for dividing the code of React components.
- Only use lazy loading in code when it's unnecessary for a website or web app's initial functionality or features.
- Set appropriate error boundaries to handle any errors that may occur if the lazy loading of the components fails.