Lazy Loading
Lazy loading defers fetching or rendering off-screen resources until they are needed. It saves bandwidth and reduces main-thread contention — but misapplied, it can harm LCP and INP.
Native lazy loading
Images and iframes support loading="lazy" in modern browsers. The browser uses heuristics (distance from viewport, connection speed) to decide when to start loading.
<img src="hero.jpg" alt="…" width="1200" height="630" fetchpriority="high">
<img src="diagram.png" alt="…" loading="lazy" decoding="async">
What not to lazy-load
- Above-the-fold hero images that drive LCP — use
fetchpriority="high"and eager loading instead. - Fonts critical to first paint — subset and preload where appropriate.
- Small icons in the initial viewport — overhead of observers can exceed savings.
Intersection Observer
For custom elements (infinite lists, modules, maps), IntersectionObserver triggers when a sentinel enters the viewport — more efficient than scroll listeners. Remember to unobserve after load to release memory.
Dynamic import()
import() lazy-loads JavaScript modules on demand — ideal for admin-only or route-specific code. Combine with route-based splitting in your bundler.