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 },},}),],};