Code Splitting in React with Lazy Components
Tags: serverless, jamstack, database, graphql
Published: 2019-12-05 20:47:33

Author: Bruno Quaresma
Date: August 16, 2019
[Originally posted on Bruno Quaresma Blog..](https://www.brunoquaresma.dev/code-split-with-lazy-components/)

---

Often during application development, we do not care much about the size of our bundle. However, as the code base grows, we need to think about it not only for speed and performance, but also to take responsibility for users’ data consumption—especially on mobile devices. So how do we load our assets as quickly as possible, and only when the user needs them, by taking advantage of concurrent browser requests?

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/b0nu3hqgo0179n1ln5kd.png)

Font: [https://docs.pushtechnology.com/cloud/latest/manual/html/designguide/solution/support/connection_limitations.html](https://docs.pushtechnology.com/cloud/latest/manual/html/designguide/solution/support/connection_limitations.html)

A good option for this is to use the Code Split technique. This technique consists of splitting the code into smaller chunks and loading these chunks only when they are required. Let’s see a use case.

In [Fauna Dashboard](https://dashboard.fauna.com/), we have pages where we are using code editors with heavy dependencies even after gzip. We do not want to put this in the main chunk, because this will make the first rendering longer and more costly than necessary on pages where the code editor is not needed. For this case, splitting code is a good option and I’ll show you how to do it without any headaches. To get started, let’s code something and run some analyses.

Let’s use [create-react-app](https://github.com/facebook/create-react-app) to start a new React project and create the components:
```
create-react-app lazy-demo
cd lazy-demo
yarn add @reach/router react-ace
```

**App.jsx**
```
import React from "react";
import { Router, Link } from "@reach/router";
import Home from "./Home";
import Code from "./Code";

const App = () => {
  return (
    <Router>
      <Home path="/"> />
      <Code path="code" />
    </Router>
  );
};

export default App;
```

**Home.jsx**
```
import React from "react";
import { Link } from "@reach/router";

const Home = () => (
  <>
    <h1>Home</h1>
    <Link to="/code">Go to code editor</Link>
  </> 
);

export default Home;
```

**Code.jsx**
```
import React from "react";
import CodeEditor from "./CodeEditor";

const Code = () => (
  <>
    <h1>Code</h1>
    <CodeEditor />
  </>
);

export default Code;
```
**CodeEditor.jsx**
```
import React, { Lazy } from "react";
import AceEditor from "react-ace";

import "brace/mode/java";
import "brace/theme/github";

const CodeEditor = () => (
  <AceEditor mode="java" theme="github" onChange={() => {}} name="code" />
);

export default CodeEditor;
```
Now let’s take a look at how our bundle is generated and how to optimize it using [source-map-explorer](https://github.com/danvk/source-map-explorer#readme).
```
yarn add source-map-explorer
```
**package.json**
```
"scripts": {
    "analyze": "source-map-explorer 'build/static/js/*.js'",
```
```
yarn build
yarn analyze
```
After running the analyses, we can see a simple chart in the browser:

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/xur52bi12rx5ocerj7yy.png)

We can also look at the time it takes to load the page. For a better comparison, I’m loading this page with cache disabled and on a slow 3G connection.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/dlhet32xb5bhl4bygj0r.png)

As we can see in the image, all our code is in only one piece. It does not use the power of parallel requests and loads unnecessary code the first time, which causes some delay in the first rendering. To do this, we can turn our CodeEditor component into a slow component.

**LazyCodeEditor**
```
import React, { Suspense } from 'react'
const CodeEditor = React.lazy(() => import('./CodeEditor'))

export default function LazyCodeEditor(props) {
  return (
    /* Here you can pass a better fallback if you want to. */
    <Suspense fallback="{<></>}>
      <CodeEditor {...props} />
    </Suspense>
  )
}
```
- **React.lazy** allow us to do dynamic imports.
- **Suspense** will render the component only when it is resolved. You can use the **fallback** props to pass a loader component.

So we’re loading the **CodeEditor** only when this code is called and not at build time. The **Suspense** component will wait for the **CodeEditor** to be resolved and display it, meanwhile displaying the fallback. Now, to see the difference, we’ll import the **LazyCodeEditor** instead of the **CodeEditor** and run some analyses again.

**Code.jsx**
```
import React from "react";
import LazyCodeEditor from "./LazyCodeEditor";

const Code = () => (
  <>
    <h1>Code</h1>
    <LazyCodeEditor />
  </>
);

export default Code;
```
```
yarn build
yarn analyze
```

We can see the <code>brace</code> and <code>react-ace</code> split into a different chunk:

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/h8zugnz3f4upu2hg5tsr.png)

And we can see that initial load time has decreased.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/vony0apai8lb8vkvw7kr.png)

Our app only loads the chunks related to the code-editor when the user needs them:

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/czpqiowx26c2u0m9bgoj.png)

Now, we have an app which uses **Code Splitting** to have better performance and user experience as well. I hope you have enjoyed this article and it has been useful to you. Thanks for reading!

**REFERENCES**

[https://reactjs.org/docs/code-splitting.html](https://reactjs.org/docs/code-splitting.html)