When using React Router's framework features, your application is automatically code split to improve the performance of initial load times when users visit your application.
Consider this simple route config:
import {
type RouteConfig,
route,
} from "@react-router/dev/routes";
export default [
route("/contact", "./contact.tsx"),
route("/about", "./about.tsx"),
] satisfies RouteConfig;
Instead of bundling all routes into a single giant build, the modules referenced (contact.tsx and about.tsx) become entry points to the bundler.
Because these entry points are coupled to URL segments, React Router knows just from a URL which bundles are needed in the browser, and more importantly, which are not.
If the user visits "/about" then the bundles for about.tsx will be loaded but not contact.tsx. This drastically reduces the JavaScript footprint for initial page loads and speeds up your application.
React Router can also split client-side route exports (clientLoader, clientAction, clientMiddleware, HydrateFallback) into separate chunks that can be loaded independently from the route component.
This allows these exports to be fetched and executed while the component code is still downloading, improving performance for client-side data loading.
This behavior is enabled by default. You can set splitRouteModules to false to opt out, or "enforce" to require all routes to be splittable. The "enforce" option will cause build failures for routes that cannot be split due to shared code.
import type { Config } from "@react-router/dev/config";
export default {
splitRouteModules: false,
} satisfies Config;
Any server-only Route Module APIs will be removed from the bundles. Consider this route module:
export async function loader() {
return { message: "hello" };
}
export async function action() {
console.log(Date.now());
return { ok: true };
}
export async function headers() {
return { "Cache-Control": "max-age=300" };
}
export default function Component({ loaderData }) {
return <div>{loaderData.message}</div>;
}
After building for the browser, only the Component will still be in the bundle, so you can use server-only code in the other module exports.