Advanced Code Splitting & Bundling
Master code splitting strategies: Route-based splitting, component-based splitting, dynamic imports, bundle optimization, tree shaking, Module Federation, and modern bundler configurations.
🛤️ 1. Route-based Code Splitting
Why serve a buffet when your user only wants a snack? 🍕 Route-based splitting loads only what's needed per page — your users will thank you with faster load times and bigger smiles!
🔴 Impact: CRITICAL — The #1 performance win for most apps — can cut initial bundle size by 50%+ instantly! ⚡
📋 In this section: React.lazy • Suspense Boundaries • Next.js Auto-splitting • Dynamic Route Imports
// ✅ React.lazy for route splittingimport { lazy, Suspense } from 'react';import { BrowserRouter, Routes, Route } from 'react-router-dom';const Home = lazy(() => import('./pages/Home'));const About = lazy(() => import('./pages/About'));const Dashboard = lazy(() => import('./pages/Dashboard'));function App() {return (<BrowserRouter><Suspense fallback={<PageLoader />}><Routes><Route path="/" element={<Home />} /><Route path="/about" element={<About />} /><Route path="/dashboard" element={<Dashboard />} /></Routes></Suspense></BrowserRouter>);}// ✅ Next.js automatic route splitting// app/dashboard/page.tsx - automatically code splitexport default function DashboardPage() {return <div>Dashboard</div>;}// ✅ Dynamic route importsconst loadDashboard = () => import('./pages/Dashboard');function App() {const [showDashboard, setShowDashboard] = useState(false);const [Dashboard, setDashboard] = useState<React.ComponentType | null>(null);const handleClick = async () => {const module = await loadDashboard();setDashboard(() => module.default);setShowDashboard(true);};return (<div><button onClick={handleClick}>Load Dashboard</button>{showDashboard && Dashboard && (<Suspense fallback={<div>Loading...</div>}><Dashboard /></Suspense>)}</div>);}
🧩 2. Component-based Splitting
Got a chunky chart or a beefy editor hiding below the fold? 🏋️ Don't load it until your user actually needs it — lazy loading components is like meal-prepping for performance! 📦✨
🟠 Impact: HIGH — Heavy components can bloat your bundle by hundreds of KBs — lazy load them and watch your TTI plummet! 📉
📋 In this section: Lazy Component Loading • Intersection Observer • Viewport-based Loading • Preload on Hover
// ✅ Lazy load heavy componentsimport { lazy, Suspense } from 'react';const HeavyChart = lazy(() => import('./HeavyChart'));const DataTable = lazy(() => import('./DataTable'));const RichEditor = lazy(() => import('./RichEditor'));function Dashboard() {const [showChart, setShowChart] = useState(false);return (<div><button onClick={() => setShowChart(true)}>Show Chart</button>{showChart && (<Suspense fallback={<ChartSkeleton />}><HeavyChart /></Suspense>)}</div>);}// ✅ Intersection Observer for viewport-based loadingfunction useLazyLoad(ref: React.RefObject<Element>) {const [isVisible, setIsVisible] = useState(false);useEffect(() => {const observer = new IntersectionObserver(([entry]) => {if (entry.isIntersecting) {setIsVisible(true);observer.disconnect();}},{ rootMargin: '50px' });if (ref.current) {observer.observe(ref.current);}return () => observer.disconnect();}, [ref]);return isVisible;}function LazyComponent() {const ref = useRef<HTMLDivElement>(null);const isVisible = useLazyLoad(ref);return (<div ref={ref}>{isVisible ? (<Suspense fallback={<div>Loading...</div>}><HeavyComponent /></Suspense>) : (<div style={{ height: '200px' }}>Placeholder</div>)}</div>);}// ✅ Preload on hoverfunction PreloadableLink({ to, children }: { to: string; children: React.ReactNode }) {const preloadRoute = () => {import(`./pages/${to}`);};return (<Linkto={to}onMouseEnter={preloadRoute}onFocus={preloadRoute}>{children}</Link>);}
🔗 3. Module Federation
Think of it as Netflix for your micro-frontends — each app shares its best components like a potluck dinner! 🎉 Module Federation lets independent teams deploy and share code seamlessly. 🤝
🔵 Impact: MEDIUM — Essential for large orgs with multiple teams — enables true micro-frontend architecture! 🏗️
📋 In this section: Host Configuration • Remote Components • Shared Dependencies • Webpack Setup
// ✅ Module Federation Host (Container)// webpack.config.jsconst ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin;module.exports = {plugins: [new ModuleFederationPlugin({name: 'host',remotes: {remoteApp: 'remote@http://localhost:3001/remoteEntry.js',},shared: {react: { singleton: true },'react-dom': { singleton: true },},}),],};// ✅ Using Remote Componentsimport { lazy, Suspense } from 'react';const RemoteButton = lazy(() => import('remoteApp/Button'));const RemoteHeader = lazy(() => import('remoteApp/Header'));function App() {return (<div><Suspense fallback={<div>Loading...</div>}><RemoteHeader /><RemoteButton onClick={() => console.log('clicked')}>Click me</RemoteButton></Suspense></div>);}// ✅ Module Federation Remote (Exposing)// webpack.config.js (Remote App)module.exports = {plugins: [new ModuleFederationPlugin({name: 'remote',filename: 'remoteEntry.js',exposes: {'./Button': './src/Button','./Header': './src/Header',},shared: {react: { singleton: true },'react-dom': { singleton: true },},}),],};