Code splitting

3 snippets across 2 stacks — React, JavaScript

REReact

Suspense & Lazy Loading

RE · Patterns
syntax
const LazyComponent = React.lazy(() => import('./Component'));

<Suspense fallback={<Loading />}>
  <LazyComponent />
</Suspense>
example
import { lazy, Suspense, useState } from 'react';

const AdminPanel = lazy(() => import('./AdminPanel'));
const UserDashboard = lazy(() => import('./UserDashboard'));

function App({ role }) {
  return (
    <Suspense fallback={<div className="spinner">Loading...</div>}>
      {role === 'admin' ? <AdminPanel /> : <UserDashboard />}
    </Suspense>
  );
}

Note React.lazy only works with default exports. For named exports, create an intermediate module that re-exports as default. Suspense can also wrap components that use the use() hook to read promises in React 19.

Code Splitting by Route

RE · Performance
syntax
const Page = lazy(() => import('./Page'));
<Suspense fallback={<Spinner />}>
  <Page />
</Suspense>
example
import { lazy, Suspense } from 'react';

const Home = lazy(() => import('./pages/Home'));
const Products = lazy(() => import('./pages/Products'));
const Account = lazy(() => import('./pages/Account'));

function AppRouter() {
  const [route, setRoute] = useState('home');

  return (
    <nav>
      <button onClick={() => setRoute('home')}>Home</button>
      <button onClick={() => setRoute('products')}>Products</button>
      <button onClick={() => setRoute('account')}>Account</button>

      <Suspense fallback={<div className="page-loader">Loading page...</div>}>
        {route === 'home' && <Home />}
        {route === 'products' && <Products />}
        {route === 'account' && <Account />}
      </Suspense>
    </nav>
  );
}

Note Route-based code splitting gives the biggest bundle size reduction because entire page components and their dependencies are loaded on demand. Place the Suspense boundary around the lazy components, not the entire app.

JSJavaScript

Dynamic Import

JS · Modules
syntax
const module = await import("./module.js");
example
async function loadEditor() {
  const { EditorView } = await import("./editor.js");
  return new EditorView(document.getElementById("editor"));
}

// Conditional loading
if (needsCharting) {
  const { renderChart } = await import("./charts.js");
  renderChart(data);
}

Note Returns a promise that resolves to the module namespace. Ideal for code-splitting, lazy loading, and conditional imports. Works at runtime, not just at the top of a file.