Home
React
Performance: Code Splitting
Daniel Nguyen
Daniel Nguyen
July 26, 2025
1 min

Code splitting divides your JavaScript bundle into smaller chunks that can load on demand instead of downloading everything upfront.

Think: stream one episode, not the whole season.

1. Lazy Load Components

Use React.lazy with Suspense to load a component when it is first rendered.

import { lazy, Suspense } from "react";
const SmileyFace = lazy(() => import("./SmileyFace"));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<SmileyFace />
</Suspense>
);
}
  • Reduces the JavaScript required for the initial page.
  • Defers downloading and evaluating the component’s module until needed.
  • Displays fallback UI while the module is loading.

2. Load Heavy Features on Demand

Avoid loading expensive features, such as a Three.js globe, until the user requests them.

import { lazy, Suspense, useState } from "react";
const Globe = lazy(() => import("./Globe"));
function App() {
const [showGlobe, setShowGlobe] = useState(false);
return (
<>
<button onClick={() => setShowGlobe(true)}>
Open Globe
</button>
{showGlobe && (
<Suspense fallback={<div>Loading globe...</div>}>
<Globe />
</Suspense>
)}
</>
);
}

The globe module isn’t requested by this component until showGlobe becomes true and React attempts to render it.

This keeps the initial experience lighter, especially when the feature is rarely used.

3. Preload on Hover or Focus

If users are likely to open a feature, start downloading its module before they click.

const preloadGlobe = () => import("./Globe");
function GlobeLauncher({ onOpen }: { onOpen: () => void }) {
return (
<button
onPointerEnter={preloadGlobe}
onFocus={preloadGlobe}
onClick={onOpen}
>
Open Globe
</button>
);
}

The dynamic import starts loading the module early. When React.lazy later requests the same module, the module loader can reuse the in-flight or cached import.

Use this selectively: preloading every feature can increase network usage and compete with more important resources.

4. Keep UI Responsive with useTransition

When revealing a lazy-loaded component, useTransition can mark the state update as non-urgent.

import { lazy, Suspense, useState, useTransition } from "react";
const Globe = lazy(() => import("./Globe"));
function App() {
const [showGlobe, setShowGlobe] = useState(false);
const [isPending, startTransition] = useTransition();
function openGlobe() {
startTransition(() => {
setShowGlobe(true);
});
}
return (
<>
<button onClick={openGlobe}>Open Globe</button>
{isPending && <span>Preparing feature...</span>}
<Suspense fallback={<div>Loading globe...</div>}>
{showGlobe && <Globe />}
</Suspense>
</>
);
}

useTransition helps React prioritize urgent interactions over non-urgent rendering work. It does not make the network request faster or guarantee that the Suspense fallback will never appear.

For transitions that reveal already-visible content, React can often keep the existing UI visible while the new content suspends.

5. Avoid Loading Indicator Flicker

For very fast requests, showing a spinner for only a few milliseconds can make the interface feel less polished.

You can delay the appearance of a loading indicator using a small delay or a utility such as spin-delay.


Tags

#ReactPerformance

Share

Daniel Nguyen

Daniel Nguyen

Frontend Developer

Frontend developer specializing in React, Next.js, and JavaScript. Writing practical guides on modern web development at Dev98.

Expertise

React
Next.js
JavaScript
TypeScript
Python

Social Media

githublinkedinyoutubewebsite

Related Posts

React Performance
Performance: Windowing
August 06, 2025
1 min
Dev98

Dev98

React · Next.js · Web development