Reactjs 18 new way Lazy Loading with Suspense in React

React’s Suspense is going to evolve over the coming months. It’s promised to game-changing on how we develop our React apps. Let’s look at some cool tricks with Suspense in the current version of React (16.8.6).

React.Suspense let you specify the loading indicator in case some components in the tree below it are not yet ready to render. Today, lazy loading components is the only use case supported by <React.Suspense>.

Currently, React.Suspense takes a single prop which is fallback, this is triggered whenever a Promise is propagated up to your Suspense fallback block. Not making sense? Don’t worry I’ll show you how simple it is below with working samples.

Lazy Loading is one of the most simple and effective ways to speed up the load time of your bundles. With React.lazy this is easier than ever and combined with Suspense it’s effortless.

To lazy load a component we just need to modify a regular import slightly:

import SomeComponent from ‘./SomeComponent’; 

Becomes:

const SomeComponent = React.lazy(() => import(‘./SomeComponent’; ));  

This now resolves as a promise (and if you check your network tab you’ll see you actually made a request for a small bundle of js).

If the module containing the SomeComponent is not yet loaded by the time your component is rendering, we must show some fallback content while we’re waiting for it to load - such as a loading indicator. This is done using the Suspense component.

Wrap your imported component in a Suspense block and as it’s loading we will see the Loading component we pass as the fallback prop.

// Before
import OtherComponent from './OtherComponent';
function MyComponent() {
return (
<div>
<OtherComponent />
</div>
);
}
// After
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
view rawlazy_react.js hosted with ❤ by GitHub

React Router & Suspense

One of the easiest ways to turbocharge your app when using React Router is using lazy loading, thanks to Suspense it’s easier than ever.

Let’s show you what it takes to convert normal routes into a super fast lazy loaded app:

// Before
import React, { Component, Suspense, lazy } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Home from './Home'
import Topics from './Topics'
import Settings from './Settings'
class App extends Component {
render() {
return (
<Router>
<div>
<ul>
<li><Link to='/'>Home</Link></li>
<li><Link to='/topics'>Topics</Link></li>
<li><Link to='/settings'>Settings</Link></li>
</ul>
<hr />
<Route exact path='/' component={Home} />
<Route path='/topics' component={Topics} />
<Route path='/settings' component={Settings} />
</div>
</Router>
)
}
}
export default App
// After
import React, { Component, Suspense, lazy } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
// Wrap each imported route in lazy import
const Home = lazy(() => import("./Home"));
const Topics = lazy(() => import("./Topics"));
const Settings = lazy(() => import("./Settings"));
class App extends Component {
render() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
<li>
<Link to="/settings">Settings</Link>
</li>
</ul>
<hr />
{/* Add Suspense around the routes so that whichever route that is loading it will show a loader */}
<Suspense fallback={<div>Loading...</div>}>
<Route exact path="/" component={Home} />
<Route path="/topics" component={Topics} />
<Route path="/settings" component={Settings} />
</Suspense>
</div>
</Router>
);
}
}
export default App;
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

You can play with the code here.

Make the web a faster place by making sure to code split anywhere possible. Since you only need your initial route first it’s always wasteful to bundle up routes that your user may never actually hit.

Note:

React.lazy and Suspense are not yet available for server-side rendering. If you want to do code-splitting in a server-rendered app, it is recommended to use Loadable Components. It has a nice guide for bundle splitting with server-side rendering.

Thanks for reading!