Problem Statement
What is code splitting in JavaScript?
Explanation
Code splitting breaks your application into smaller chunks that can be loaded on demand.
It reduces the initial bundle size, improving load time. Only load code when needed.
Modern bundlers like Webpack automatically create split points with dynamic imports.
Route-based splitting loads code for each route separately.
Component-based splitting loads heavy components only when rendered.
Understanding code splitting is crucial for optimizing large JavaScript applications.
Code Solution
SolutionRead Only
// DYNAMIC IMPORT (ES2020)
// Load module on demand
button.addEventListener('click', async () => {
const module = await import('./heavy-feature.js');
module.init();
});
// Webpack creates separate chunk automatically
// ROUTE-BASED CODE SPLITTING
// Router configuration
const routes = [
{
path: '/home',
component: () => import('./views/Home.js')
},
{
path: '/about',
component: () => import('./views/About.js')
},
{
path: '/dashboard',
component: () => import('./views/Dashboard.js')
}
];
// Load route component on navigation
async function navigateTo(path) {
const route = routes.find(r => r.path === path);
const module = await route.component();
const component = new module.default();
component.render();
}
// COMPONENT-BASED SPLITTING
// Lazy load heavy component
class App {
async loadChart() {
if (!this.ChartComponent) {
const module = await import('./Chart.js');
this.ChartComponent = module.default;
}
return new this.ChartComponent();
}
async showChart() {
const chart = await this.loadChart();
chart.render();
}
}
// REACT CODE SPLITTING
import React, {lazy, Suspense} from 'react';
// Lazy load component
const HeavyComponent = lazy(() => import('./HeavyComponent'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<HeavyComponent />
</Suspense>
);
}
// WEBPACK MAGIC COMMENTS
// Name the chunk
import(/* webpackChunkName: "chart" */ './chart.js');
// Prefetch (load when idle)
import(/* webpackPrefetch: true */ './future-page.js');
// Preload (load in parallel)
import(/* webpackPreload: true */ './critical.js');
// VENDOR SPLITTING
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};
// CONDITIONAL LOADING
let component;
if (userPreference === 'advanced') {
component = await import('./AdvancedView.js');
} else {
component = await import('./SimpleView.js');
}
component.render();
// FEATURE FLAGS WITH CODE SPLITTING
const features = await fetch('/api/features').then(r => r.json());
if (features.betaFeature) {
const betaModule = await import('./beta-feature.js');
betaModule.enable();
}
// LIBRARY SPLITTING
// Load only when needed
async function processCSV(file) {
const Papa = await import('papaparse');
return Papa.parse(file);
}
async function renderChart(data) {
const Chart = await import('chart.js');
return new Chart(data);
}
// PROGRESSIVE ENHANCEMENT
// Load basic version first
import './basic.js';
// Load enhanced version when idle
if ('requestIdleCallback' in window) {
requestIdleCallback(async () => {
await import('./enhanced.js');
});
}
// MEASURING IMPACT
// Before code splitting:
// bundle.js: 500KB (loads immediately)
// After code splitting:
// main.js: 50KB (loads immediately)
// home.js: 30KB (loads on /home)
// dashboard.js: 100KB (loads on /dashboard)
// chart.js: 200KB (loads when chart needed)
// Total still 380KB, but initial load only 50KB!
// LAZY LOADING WITH CACHE
const moduleCache = new Map();
async function loadModule(path) {
if (moduleCache.has(path)) {
return moduleCache.get(path);
}
const module = await import(path);
moduleCache.set(path, module);
return module;
}
// BENEFITS
// - Faster initial load
// - Smaller initial bundle
// - Better caching
// - Improved performance metrics
// - Better user experience