Code Splitting
Problem
Applications ship a single massive JavaScript bundle containing all routes, features, and dependencies. Users downloading the homepage must wait for the entire admin dashboard, checkout flow, and analytics code to download and parse. First contentful paint is delayed by hundreds of kilobytes of unused code, especially painful on slow networks.
Solution
Split your application at logical boundaries like routes or features using dynamic imports, loading each chunk only when needed. This shrinks the initial bundle to just what’s required for the first page, dramatically improving time-to-interactive.
Example
This example demonstrates using dynamic imports to split code by route, loading the Dashboard component only when users navigate to that route.
// Use dynamic import to create a separate bundle for the Dashboard
const Dashboard = () => import('./pages/Dashboard');
// Configure router to lazy-load the Dashboard component
{
path: '/dashboard',
component: Dashboard // Component will be loaded on-demand when this route is accessed
}
Benefits
- Dramatically reduces initial bundle size and improves time-to-interactive.
- Loads code only when needed, saving bandwidth for unused features.
- Improves perceived performance by showing content faster.
- Especially beneficial for mobile users on slow networks.
- Enables progressive loading of application features.
Tradeoffs
- Introduces loading states and delays when navigating to new routes.
- Can create jarring user experience if not paired with proper loading UI.
- Adds complexity to build configuration and debugging.
- May create more HTTP requests which can be slower on
HTTP/1.1
. - Requires careful splitting strategy to balance bundle size and request count.