- Published on
What is React Lazy And Suspense?
Overview
A post on the usage of React.Lazy and Suspend
Introduction
Web applications keep getting more complex and growing day by day. This often leads to performance issues. But we developers have to keep the end user's reach at the highest level, no matter how big the application gets. Therefore, we must make performance improvements throughout the application we develop and use resources in the most efficient way 😕.
This is very important in these times when we load all UI operations on the back of javascript. Especially if we use tools such as React, Vue, Angular, when our code is build, we get the output of a large bundle (when our code becomes a single javascript file 📦). In this bundle, there will be parts that the user will not interact with during the time spent in the application. In this bundle, only the parts that the user will interact with and the parts required for our application to work will greatly benefit our application in terms of performance 💡.
Let's try to understand the problem more clearly on a React code.
import React from 'react'
// Components
import Header from './components/Header'
import LoginModal from './components/LoginModal'
import NotificationPopup from './components/NotificationBar'
import Product from './components/Product'
import ProductReviews from './components/Product/Reviews'
import SideMenu from './components/SideMenu'
const App = () => (
<>
<Header />
<SideMenu />
<NotificationPopup />
<Product />
<ProductReviews />
<LoginModal />
</>
)
export default AppTheme: {
colors: {
primary: colors.teal,
gray: colors.neutral,
...
}
...
}
It doesn't make much sense to have some of the components that we reviewed the React code above in our bundle file. For example, Login Modal component will not be used unless the user wants to login. Likewise, the "Product Reviews" component will not be activated unless the user clicks on the product comments tab. Removing these components from our bundle file and installing them when the user interacts will greatly increase the performance of our application.
Code Splitting
We call code splitting by dividing our code into small chunks (chunk) and ensuring that these pieces are loaded optionally at runtime. It is possible to make this configuration with tools such as Webpack, Browserify, Rollup. There is also an easier one. If you are using tools like Create React App, Gatsby or Next.js, this feature comes built-in.
⚠️ If you are doing Client Side Routing in your application, you should definitely pay attention to code splitting.
Now that we understand the problem and briefly talk about code splitting, we can now move on to the part where we handle it on the React side.
React.lazy()
The method to load our components dynamically is React.lazy(). This method should be a function that wraps the component we load dynamically as a parameter.
⚠️ The parameter we give to React.lazy() should return promise.
//Usual way
import LoginModal from './components/LoginModal'
// With React.lazy() import way:
const LoginModal = React.lazy(() => import('./components/LoginModal'))
With a small change, we have loaded the LoginModal component dynamically. Now let's move on to rendering this component.
React Suspense
React's special component is Suspense, which allows us to render the component we loaded dynamically and display a backup content in the time that passes until this component is loaded. The Suspense component takes a single prop called fallback. And this fallback props is where we specify the content to render until our dynamic component is loaded or when there is any problem with the component loading.
import React, { Suspense } from 'react'
// Dynamic Imports
const LoginModal = React.lazy(() => import('./components/LoginModal'))
const App = () => {
// ...
const showLoginModal = () => {}
return (
<>
{/* ... */}
<button onClick={showLoginModal}>Login</button>
{isLoginModalOpen && (
<Suspense fallback={<div>Loading...</div>}>
<LoginModal />
</Suspense>
)}
{/* ... */}
</>
)
}//Usual way
import LoginModal from './components/LoginModal'
// With React.lazy() import way:
const LoginModal = React.lazy(() => import('./components/LoginModal'))
Simply this way to use Suspense. We can also give a component as fallback props.
<Suspense fallback={<LoadingOverlay />}>
<LoginModal />
</Suspense>