Hint
Lazy loading: load resources only when needed; code splitting: divide bundle into smaller chunks
Lazy loading defers loading of non-critical resources until they're actually needed.
Code splitting breaks your JS bundle into smaller chunks loaded on demand.
// ─── Native Lazy Loading (images, iframes) ─────────────────
<img src="hero.jpg" loading="eager" /> // load immediately
<img src="below-fold.jpg" loading="lazy" /> // load when near viewport
// ─── JS Code Splitting (Webpack/Vite) ─────────────────────
// Static import — included in main bundle
import { utils } from './utils.js';
// Dynamic import — separate chunk, loaded on demand
async function loadChart() {
const { Chart } = await import('./HeavyChart.js'); // separate bundle
new Chart(element, data);
}
// Route-based splitting (React Router)
const Dashboard = React.lazy(() => import('./Dashboard'));
const Settings = React.lazy(() => import('./Settings'));
function App() {
return (
<Suspense fallback={<Spinner />}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
);
}
// ─── IntersectionObserver lazy loading ────────────────────
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
entry.target.src = entry.target.dataset.src;
observer.unobserve(entry.target);
}
});
document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));