Optimize Web Applications for Performance: Code-Splitting and Lazy Loading in React
Tags: react, webdev, performance, lazyloading
Published: 2023-12-29 05:21:13

React makes it easy to build small to complex web applications. But the more complex the application gets, the more resources it demands. This makes it necessary to employ various optimization techniques to improve the application’s performance and the overall user satisfaction. In this article, we are going to explore how we can boost performance by code-splitting and lazy loading.

We’ll start with code splitting, then look at lazy loading, later provide a fallback while loading with Suspense() and finally conclude with useTransition().

**Code Splitting**

Your React application runs from a single JavaScript bundle file that grows as the application grows. 

The code from individual component files is imported to the application’s top-most file to make up a complete web page or application. That whole code is the "bundle".

So bundling is the process of following these imported files and combining them to make a single file that can be included on a webpage to load the entire app at once, thanks to a tool like Webpack.

When you code-split or simply split your code, you break down your code into multiple individual bundle chunks. These individual bundles might be single components in the application or name-exported functions etc. 
Splitting the code is achieved by the use of dynamic imports.

Now on regular imports, you import components on component call, and they look like:

```
import ComponentName from "./Pathname.js"
```

But dynamic imports are different, they are imported only when requested for, or when they reach expression. Look like so:

```
const ComponentName = import("./Pathname.js")
```

**React lazy**

React lazy loading is a website optimization technique aiming to boost the site's performance by loading bundles of code on demand. 

This enables avoid issues like increased initial load time, more consumption of bandwidth and system resources, overworking the browser and bad user experience, that may arise as a result of loading the entire application’s code at once.

It renders components with dynamic imports just like the regular ones except this dynamically imported component’s bundle only loads when the component is rendered. 

React.lazy() accepts a function that calls a dynamic import. The dynamic import returns a promise resolving to a module with a default export containing a React component.

```
const AnotherComponent = React.lazy(() => import("./Pathname.js"))
```

**React Suspense**

When you lazily load a component in your application, you need to let React know of it, so it sets up what can be used as placeholder while that lazy component loads on request or during "suspense". 

Suspense() is a component that wraps around your lazy component/s and accepts a DOM element fallback prop  that will be show on the DOM while the lazy component is being loaded.

On markup:

```
<Suspense fallback={<YourPageLoader />}>
    <Outlet />
</Suspense>
```

**startTransition()**

With Suspense(), the DOM is updated with the fallback prop you provided until the next lazy component is rendered. Sometimes you don’t want to totally replace the old UI while waiting for the new UI. To achieve this, use startTransition().

It freezes the current appearance until the next requested component is rendered, only then the switching takes place.

One use case is when you want to have a loading spinner above a blurred current UI’s background while the transitioning occurs.

Example: show the "lazy" dashboard when the showDashboard state is true – toggled by "see board" button on UI

```
import {useState, useTransition, lazy} from “react”;

const Dashboard = lazy(() => import(“./DashboardPath.js”));

const Home = () => {
  const [showDashboard, setShowDashboard] = useState(false);
  const [isPending, startTransition] = useTransition();
  
  return (
    <div>
      <button onClick={e => {
startTransition(() => {
setShowDashboard(prev => !prev)
})
}}>see board</button>
      <div>
{isPending && <Dashboard /> }
      </div>
    </div>
  )
}
```

In conclusion, React lazy() is a website optimization technique that renders the split code in dynamic imports on demand. React Suspense() offers a fallback element that shows while the newly requested lazy component loads. React useTransition() helps preserve the current UI until the component is rendered. When used, it improves the application's performance and the user experience.