$ // ❌ Every time `count` changes, ALL children re-render function Dashboard() { const [count, setCount] = useState(0); return ( <> <button onClick={() => setCount(count + 1)}>Update</button> <HeavyChart /> {/* Re-renders even though it doesn't use count */} <UserTable /> {/* Same problem */} <ActivityFeed /> {/* Same problem */} </> ); } COMMAND_BLOCK: // ❌ Every time `count` changes, ALL children re-render function Dashboard() { const [count, setCount] = useState(0); return ( <> <button onClick={() => setCount(count + 1)}>Update</button> <HeavyChart /> {/* Re-renders even though it doesn't use count */} <UserTable /> {/* Same problem */} <ActivityFeed /> {/* Same problem */} </> ); } COMMAND_BLOCK: // ❌ Every time `count` changes, ALL children re-render function Dashboard() { const [count, setCount] = useState(0); return ( <> <button onClick={() => setCount(count + 1)}>Update</button> <HeavyChart /> {/* Re-renders even though it doesn't use count */} <UserTable /> {/* Same problem */} <ActivityFeed /> {/* Same problem */} </> ); } CODE_BLOCK: // ✅ Now these components only re-render when their own props change const HeavyChart = React.memo(function HeavyChart() { return <div>...chart...</div>; }); const UserTable = React.memo(function UserTable({ users }) { return <table>...table...</table>; }); CODE_BLOCK: // ✅ Now these components only re-render when their own props change const HeavyChart = React.memo(function HeavyChart() { return <div>...chart...</div>; }); const UserTable = React.memo(function UserTable({ users }) { return <table>...table...</table>; }); CODE_BLOCK: // ✅ Now these components only re-render when their own props change const HeavyChart = React.memo(function HeavyChart() { return <div>...chart...</div>; }); const UserTable = React.memo(function UserTable({ users }) { return <table>...table...</table>; }); COMMAND_BLOCK: -weight: 500;">npm -weight: 500;">install --save-dev webpack-bundle-analyzer npx webpack-bundle-analyzer build/static/js/*.js COMMAND_BLOCK: -weight: 500;">npm -weight: 500;">install --save-dev webpack-bundle-analyzer npx webpack-bundle-analyzer build/static/js/*.js COMMAND_BLOCK: -weight: 500;">npm -weight: 500;">install --save-dev webpack-bundle-analyzer npx webpack-bundle-analyzer build/static/js/*.js COMMAND_BLOCK: // ❌ Before — everything loaded upfront import HeavyChartPage from './pages/HeavyChartPage'; import AdminPanel from './pages/AdminPanel'; import ReportsPage from './pages/ReportsPage'; // ✅ After — only loaded when user visits that page import { lazy, Suspense } from 'react'; const HeavyChartPage = lazy(() => import('./pages/HeavyChartPage')); const AdminPanel = lazy(() => import('./pages/AdminPanel')); const ReportsPage = lazy(() => import('./pages/ReportsPage')); function App() { return ( <Suspense fallback={<div>Loading...</div>}> <Routes> <Route path="/charts" element={<HeavyChartPage />} /> <Route path="/admin" element={<AdminPanel />} /> <Route path="/reports" element={<ReportsPage />} /> </Routes> </Suspense> ); } COMMAND_BLOCK: // ❌ Before — everything loaded upfront import HeavyChartPage from './pages/HeavyChartPage'; import AdminPanel from './pages/AdminPanel'; import ReportsPage from './pages/ReportsPage'; // ✅ After — only loaded when user visits that page import { lazy, Suspense } from 'react'; const HeavyChartPage = lazy(() => import('./pages/HeavyChartPage')); const AdminPanel = lazy(() => import('./pages/AdminPanel')); const ReportsPage = lazy(() => import('./pages/ReportsPage')); function App() { return ( <Suspense fallback={<div>Loading...</div>}> <Routes> <Route path="/charts" element={<HeavyChartPage />} /> <Route path="/admin" element={<AdminPanel />} /> <Route path="/reports" element={<ReportsPage />} /> </Routes> </Suspense> ); } COMMAND_BLOCK: // ❌ Before — everything loaded upfront import HeavyChartPage from './pages/HeavyChartPage'; import AdminPanel from './pages/AdminPanel'; import ReportsPage from './pages/ReportsPage'; // ✅ After — only loaded when user visits that page import { lazy, Suspense } from 'react'; const HeavyChartPage = lazy(() => import('./pages/HeavyChartPage')); const AdminPanel = lazy(() => import('./pages/AdminPanel')); const ReportsPage = lazy(() => import('./pages/ReportsPage')); function App() { return ( <Suspense fallback={<div>Loading...</div>}> <Routes> <Route path="/charts" element={<HeavyChartPage />} /> <Route path="/admin" element={<AdminPanel />} /> <Route path="/reports" element={<ReportsPage />} /> </Routes> </Suspense> ); } COMMAND_BLOCK: // ❌ This runs on every render — even unrelated ones function UserTable({ users, searchQuery }) { // This heavy calculation runs EVERY time const filteredUsers = users .filter(user => user.name.includes(searchQuery)) .sort((a, b) => a.name.localeCompare(b.name)); return <table>...</table>; } COMMAND_BLOCK: // ❌ This runs on every render — even unrelated ones function UserTable({ users, searchQuery }) { // This heavy calculation runs EVERY time const filteredUsers = users .filter(user => user.name.includes(searchQuery)) .sort((a, b) => a.name.localeCompare(b.name)); return <table>...</table>; } COMMAND_BLOCK: // ❌ This runs on every render — even unrelated ones function UserTable({ users, searchQuery }) { // This heavy calculation runs EVERY time const filteredUsers = users .filter(user => user.name.includes(searchQuery)) .sort((a, b) => a.name.localeCompare(b.name)); return <table>...</table>; } COMMAND_BLOCK: // ✅ Only recalculates when users or searchQuery actually changes function UserTable({ users, searchQuery }) { const filteredUsers = useMemo(() => { return users .filter(user => user.name.includes(searchQuery)) .sort((a, b) => a.name.localeCompare(b.name)); }, [users, searchQuery]); return <table>...</table>; } COMMAND_BLOCK: // ✅ Only recalculates when users or searchQuery actually changes function UserTable({ users, searchQuery }) { const filteredUsers = useMemo(() => { return users .filter(user => user.name.includes(searchQuery)) .sort((a, b) => a.name.localeCompare(b.name)); }, [users, searchQuery]); return <table>...</table>; } COMMAND_BLOCK: // ✅ Only recalculates when users or searchQuery actually changes function UserTable({ users, searchQuery }) { const filteredUsers = useMemo(() => { return users .filter(user => user.name.includes(searchQuery)) .sort((a, b) => a.name.localeCompare(b.name)); }, [users, searchQuery]); return <table>...</table>; } COMMAND_BLOCK: -weight: 500;">npm -weight: 500;">install react-window COMMAND_BLOCK: -weight: 500;">npm -weight: 500;">install react-window COMMAND_BLOCK: -weight: 500;">npm -weight: 500;">install react-window COMMAND_BLOCK: import { FixedSizeList } from 'react-window'; // ❌ Before — renders ALL 2000 rows in the DOM function UserList({ users }) { return ( <div> {users.map(user => <UserRow key={user.id} user={user} />)} </div> ); } // ✅ After — only renders ~20 visible rows at any time function UserList({ users }) { const Row = ({ index, style }) => ( <div style={style}> <UserRow user={users[index]} /> </div> ); return ( <FixedSizeList height={600} itemCount={users.length} itemSize={50} width="100%" > {Row} </FixedSizeList> ); } COMMAND_BLOCK: import { FixedSizeList } from 'react-window'; // ❌ Before — renders ALL 2000 rows in the DOM function UserList({ users }) { return ( <div> {users.map(user => <UserRow key={user.id} user={user} />)} </div> ); } // ✅ After — only renders ~20 visible rows at any time function UserList({ users }) { const Row = ({ index, style }) => ( <div style={style}> <UserRow user={users[index]} /> </div> ); return ( <FixedSizeList height={600} itemCount={users.length} itemSize={50} width="100%" > {Row} </FixedSizeList> ); } COMMAND_BLOCK: import { FixedSizeList } from 'react-window'; // ❌ Before — renders ALL 2000 rows in the DOM function UserList({ users }) { return ( <div> {users.map(user => <UserRow key={user.id} user={user} />)} </div> ); } // ✅ After — only renders ~20 visible rows at any time function UserList({ users }) { const Row = ({ index, style }) => ( <div style={style}> <UserRow user={users[index]} /> </div> ); return ( <FixedSizeList height={600} itemCount={users.length} itemSize={50} width="100%" > {Row} </FixedSizeList> ); } CODE_BLOCK: 1. ✅ Run React DevTools Profiler — find what's actually slow 2. ✅ Add React.memo to components that re-render unnecessarily 3. ✅ Run Webpack Bundle Analyzer — find what's bloating your bundle 4. ✅ Lazy load routes and heavy components with React.lazy 5. ✅ Wrap expensive calculations in useMemo 6. ✅ Virtualize long lists with react-window 7. ✅ Enable React Compiler if on React 19+ — auto memoization! CODE_BLOCK: 1. ✅ Run React DevTools Profiler — find what's actually slow 2. ✅ Add React.memo to components that re-render unnecessarily 3. ✅ Run Webpack Bundle Analyzer — find what's bloating your bundle 4. ✅ Lazy load routes and heavy components with React.lazy 5. ✅ Wrap expensive calculations in useMemo 6. ✅ Virtualize long lists with react-window 7. ✅ Enable React Compiler if on React 19+ — auto memoization! CODE_BLOCK: 1. ✅ Run React DevTools Profiler — find what's actually slow 2. ✅ Add React.memo to components that re-render unnecessarily 3. ✅ Run Webpack Bundle Analyzer — find what's bloating your bundle 4. ✅ Lazy load routes and heavy components with React.lazy 5. ✅ Wrap expensive calculations in useMemo 6. ✅ Virtualize long lists with react-window 7. ✅ Enable React Compiler if on React 19+ — auto memoization! - Install React DevTools in Chrome - Open DevTools → Profiler tab - Click Record - Interact with your slow component - Stop recording → Look at the Flame Chart - Joined Mar 1, 2026