Frontend Development 9 min read

Using React.lazy and Suspense for Code Splitting and Lazy Loading

This article explains how React 16.6 introduced React.lazy and Suspense to simplify component code splitting and lazy loading, discusses why code splitting is needed, demonstrates dynamic import() usage, compares React-loadable with the built‑in APIs, and shows advanced patterns such as nested Suspense boundaries.

Qunar Tech Salon
Qunar Tech Salon
Qunar Tech Salon
Using React.lazy and Suspense for Code Splitting and Lazy Loading

In modern front‑end development, bundling all JavaScript into a single file can cause large bundle sizes and slow page loads. React 16.6 added React.lazy and Suspense to make code splitting and lazy loading straightforward.

Why split code? With ES6 modules, Babel, and bundlers like Webpack, developers can modularise code, but a single bundle grows as the application expands. Code splitting creates multiple bundles that can be loaded on demand, improving performance.

Dynamic import() is the primary way to split code. It returns a Promise that loads the requested module asynchronously. Webpack treats each import() call as a separate chunk, which the browser fetches when needed.

import(/* webpackChunkName: "moment" */ 'moment')

When the browser encounters this call, it creates a separate moment chunk and loads it only when the code executes.

Asynchronous component loading can be implemented manually by loading a module in componentDidMount and storing it in state:

const LoadDescription = () => import('./Description');
class App extends React.Component {
  state = { Description: null };
  componentDidMount() {
    LoadDescription.then(Description => {
      this.setState({ Description: Description.default });
    });
  }
  render() {
    const { Description } = this.state;
    return (
MyMovie
{Description ?
: 'Loading...'}
);
  }
}

While this works, each lazy component needs its own loading UI, which can lead to many loading spinners on a page.

React‑loadable is a third‑party higher‑order component that abstracts this pattern:

import Loadable from 'react-loadable';
const LoadableDescription = Loadable({
  loader: () => import('./Description'),
  loading: () =>
Loading
});
function App() {
  return (
MyMovie
);
}

However, React now provides a built‑in solution that avoids the extra loading component per lazy module.

Using React.lazy and Suspense :

import React, { Suspense } from 'react';
const Description = React.lazy(() => import('./Description'));
function App() {
  return (
MyMovie
);
}

Suspense displays the fallback UI until the lazy component resolves. Multiple lazy components can share a single Suspense boundary, so only one loading indicator appears.

When several lazy components are nested, each Suspense creates an independent loading region. For example, nesting a second Suspense with a different fallback isolates its loading state:

function App() {
  return (
MyMovie
);
}

This pattern ensures that while AnotherLazyComponent is loading, the already‑loaded Description remains visible.

In summary, upgrading to React 16.6 enables developers to use React.lazy and Suspense for simple, efficient code splitting without additional libraries. The full source code is available on GitHub.

Related links: React 16.6 release blog React.lazy and Suspense tutorial Error boundaries with lazy loading React code‑splitting docs Webpack code‑splitting guide React‑loadable repository

ReActwebpacklazy loadingCode SplittingSuspenseReact.lazy
Qunar Tech Salon
Written by

Qunar Tech Salon

Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.