React cookbook · Beginner
Split your bundle by route
Reduce initial JavaScript so the first page loads faster.
Approach
Load each route's component on demand with React Router's lazy route property (or React.lazy + Suspense). Keep shared layout code in the main bundle, show a lightweight fallback, and prefetch likely next routes on hover.
Solution
import { createBrowserRouter, RouterProvider } from "react-router";
const router = createBrowserRouter([
{
path: "/",
Component: RootLayout, // in the main bundle
children: [
{ index: true, Component: Home },
{ path: "reports", lazy: async () => ({ Component: (await import("./routes/Reports")).default }) },
{ path: "settings", lazy: async () => ({ Component: (await import("./routes/Settings")).default }) },
],
},
]);
export function App() {
return <RouterProvider router={router} />;
}
// Prefetch on hover
export function ReportsLink() {
return <Link to="/reports" onMouseEnter={() => import("./routes/Reports")}>Reports</Link>;
}
Pitfalls
- Splitting tiny components (more requests, no gain).
- No handling for chunk load failures after deploys.
- Lazy-loading the above-the-fold landing page.
Variations
React.lazyfor heavy widgets (charts, editors) within a page.- Analyze bundles with
rollup-plugin-visualizer/vite-bundle-visualizer.
Further reading: React Router: lazy routes
Reference: https://reactrouter.com/start/data/route-object#lazy
More React recipes
- Add optimistic updates to a todo list
- Build an accessible modal dialog
- Build infinite scroll with TanStack Query
- Call a cookie-authenticated API with CSRF protection
- Debounce a search input in React
- Handle errors gracefully with error boundaries
- Implement dark mode that follows the system
- Poll a long-running job's status