# Lazy Loading and code splitting

The new release of **React 16.6** rolled in with some new features that can be used to add more power to React components with little amounts of effort.

Two of these new features are `React.Suspense` and `React.lazy()`, which make it very easy to apply code-splitting and lazy-loading to React components.

This article focuses on how these two new features can be used in React applications and the new potentials they open up to React developers.

#### Code-splitting

Writing JavaScript applications has evolved over the last few years. With the advent of **ES6**(modules), transpilers like [**Babel**](https://babeljs.io/), and bundlers like [**Webpack**](https://webpack.js.org/) and [**Browserify**](http://browserify.org/), JavaScript applications can now be written in a completely modular pattern for easy maintainability.

Usually, each module gets imported and merged into a single file called the ***bundle***, and then the bundle is included on a webpage to load the entire app. However, as the app grows, the bundle size starts becoming too large and hence begins to impact page load times.

Bundlers like Webpack and Browserify provide support for ***code-splitting***, which involves splitting the code into different bundles which can be loaded on demand (***lazy-loaded***) instead of being loaded all at once, thereby improving the performance of the app.

#### Dynamic Imports

One of the major ways of splitting code is using *dynamic imports*. Dynamic imports leverage on the **`import()`** syntax, which is not yet part of the JavaScript language standard but is still a proposal that is expected to be accepted soon.

Calling `import()` to load a module relies on JavaScript Promises. Hence, it returns a promise that is fulfilled with the loaded module or rejected if the module could not be loaded.

> For older browsers, a polyfill like [es6-promise](https://github.com/stefanpenner/es6-promise) should be used to shim `Promise`.

Here is what it looks like to dynamically import a module for an app bundled with Webpack:

![](https://i2.wp.com/storage.googleapis.com/blog-images-backup/1*pPlzZBu5mfrpwRYEfNH3pw.png?zoom=2\&resize=730%2C229\&ssl=1)

When Webpack sees this syntax, it knows to dynamically create a separate bundle file for the `moment` library.

For React apps, code-splitting using dynamic `import()` happens on the fly if boilerplates like [`create-react-app`](https://facebook.github.io/create-react-app/) or [`Next.js`](https://nextjs.org/) is being used.

However, if a custom Webpack setup is being used, then you need to check the [Webpack guide](https://webpack.js.org/guides/code-splitting/) for setting up code-splitting. For Babel transpiling, you also need the [babel-plugin-syntax-dynamic-import](https://yarnpkg.com/en/package/babel-plugin-syntax-dynamic-import) plugin, to allow Babel parse dynamic `import()` correctly.

#### Code-splitting React components

Several techniques have been in use for code-splitting React components. A common approach is applying dynamic `import()` to lazy-load Route components for an application — this is usually referred to as ***route-based*** *code-splitting*.

However, there is a very popular package for code-splitting React components called [**react-loadable**](https://github.com/jamiebuilds/react-loadable). It provides a higher-order component (HOC) for loading React components with promises, leveraging on the dynamic `import()` syntax.

Consider the following React component called `MyComponent`:

![](https://i1.wp.com/storage.googleapis.com/blog-images-backup/1*fqiB8MnSLC65lS8VW61ulg.png?zoom=2\&resize=730%2C338\&ssl=1)

Here, the `OtherComponent` is not required until `MyComponent` is getting rendered. However, because we are importing `OtherComponent` statically, it gets bundled together with `MyComponent`.

We can use **`react-loadable`** to defer loading `OtherComponent` until when we are rendering `MyComponent`, thereby splitting the code into separate bundles. Here is the `OtherComponent` lazy-loaded using **`react-loadable`**.

![](https://i2.wp.com/storage.googleapis.com/blog-images-backup/1*GTH1erosjH6zpmFk54bkqQ.png?zoom=2\&resize=730%2C483\&ssl=1)

Here, you see that the component is imported using the dynamic `import()`syntax and assigned to the `loader` property in the options object.

**React-loadable** also uses a `loading` property to specify a fallback component that will be rendered while waiting for the actual component to load.

*You can learn more about what you can accomplish with* **`react-loadable`** *in this* [*documentation*](https://github.com/jamiebuilds/react-loadable/blob/master/README.md).

#### Using Suspense and React.lazy()

In **React 16.6**, support for component-based code-splitting and lazy-loading has been added via **`React.lazy()`** and **`React.Suspense`**.

> `React.lazy()` and `Suspense` are not yet available for server-side rendering. For server-side code-splitting, `React Loadable` should still be used.

#### React.lazy()

`React.lazy()` makes it easy to create components that are loaded using dynamic `import()` but are rendered like regular components. This will automatically cause the bundle containing the component to be loaded when the component is rendered.

`React.lazy()` takes a function as its argument that must return a *promise* by calling `import()` to load the component. **The returned Promise resolves to a module with a default export containing the React component.**

![](/files/-LkTijvOFv24mjwHoM0F)

#### Suspense

> A component created using `React.lazy()` only gets loaded when it needs to be rendered.

Hence, there is need to display some form of placeholder content while the lazy component is being loaded — possibly a loading indicator. This is exactly what **`React.Suspense`** was created for.

`React.Suspense` is a component that is meant for wrapping lazy components. You can wrap multiple lazy components at different hierarchy levels with a single `Suspense` component.

The `Suspense` component takes a `fallback` prop that accepts the React elements you want rendered as placeholder content while all the lazy components get loaded.

![](https://i1.wp.com/storage.googleapis.com/blog-images-backup/1*mgL3noFcWjUZRoA5ZfynFw.png?zoom=2\&resize=730%2C367\&ssl=1)

> An error boundary can be placed anywhere above lazy components to show nice user experience if a lazy component fails to load.

I have created a very simple demo on **CodeSandbox** to demonstrate using `React.lazy()` and `Suspense` for lazy-loading components. example on same is available here&#x20;

{% embed url="<https://codesandbox.io/s/new-4uirl>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tkssharma.gitbook.io/react-training/miscellaneous-items-day-11/lazy-loading-and-code-splitting.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
