What Is Lazy Loading — Deferred Resource Loading Explained
In this tutorial, you will learn about What Is Lazy Loading. We cover key concepts, practical examples, and best practices to help you master this topic.
Lazy loading defers loading non-critical resources until needed, improving initial page load time, reducing bandwidth, and enhancing Core Web Vitals.
What You'll Learn
By the end of this tutorial, you'll understand what lazy loading is, why it matters for web performance, the different types of lazy loading (images, iframes, JS, CSS), and how to measure its impact.
Why It Matters
The average webpage is over 2MB, with images accounting for 50-70% of that weight. Loading everything upfront wastes bandwidth and slows initial render. Lazy loading defers what's not immediately visible, making pages load faster.
Real-World Use
A news article page has 20 images, but only the first 2 are visible above the fold. Lazy loading defers the remaining 18 images until the user scrolls. Initial page load drops from 3.2MB to 0.4MB, and Lighthouse performance improves by 40 points.
Lazy Loading Flow
graph TD
A[Page Load] --> B[Load critical
above-fold content]
A --> C[Defer non-critical
resources]
B --> D[User sees
initial page]
D --> E[User scrolls
or interacts]
E --> F{Resource needed?}
F -->|Yes| G[Load resource
on demand]
F -->|No| H[Keep deferred]
G --> I[Display content]
H --> J[Save bandwidth]
style B fill:#27ae60,color:#fff
style C fill:#f39c12,color:#fff
style G fill:#4a90d9,color:#fff
style J fill:#27ae60,color:#fff
Native Lazy Loading
<!-- Native lazy loading — simplest approach -->
<img src="large-photo.jpg" alt="Gallery photo" loading="lazy" width="800" height="600">
<iframe src="widget.html" loading="lazy" width="400" height="300"></iframe>
<!-- Eager loading for critical images -->
<img src="hero.jpg" alt="Hero image" loading="eager" fetchpriority="high">
<!-- Browser support detection -->
<script>
if ('loading' in HTMLImageElement.prototype) {
console.log('Native lazy loading supported');
document.querySelectorAll('img[loading="lazy"]').forEach(img => {
img.src = img.dataset.src;
});
} else {
console.log('Falling back to Intersection Observer');
loadLazyImagesFallback();
}
</script>
Measuring Impact
// Performance measurement before/after lazy loading
const perfComparison = {
before: {
pageWeight: '3.2 MB',
imagesLoaded: 20,
loadTime: '4.2s',
lighthousePerformance: 45,
lighthouseLCP: '3.1s'
},
after: {
pageWeight: '0.4 MB (initial)',
imagesLoaded: 2,
loadTime: '1.1s',
lighthousePerformance: 92,
lighthouseLCP: '0.8s'
},
improvement: {
weightReduction: '87.5%',
loadTimeImprovement: '73.8%',
performanceScore: '+47 points'
}
};
// Test script for measuring lazy loading impact
async function measureLazyLoading() {
const metrics = {
totalImages: document.images.length,
lazyImages: document.querySelectorAll('img[loading="lazy"]').length,
eagerImages: document.querySelectorAll('img[loading="eager"]').length,
totalSize: 0,
loadedSize: 0
};
// Monitor network requests
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
if (entry.initiatorType === 'img') {
metrics.totalSize += entry.transferSize || entry.encodedBodySize;
if (entry.entryType === 'resource') {
metrics.loadedSize += entry.transferSize || entry.encodedBodySize;
}
}
});
});
observer.observe({ entryTypes: ['resource'] });
// Report metrics after page load
window.addEventListener('load', () => {
setTimeout(() => {
console.log('Lazy Loading Metrics:', metrics);
console.log(`Bandwidth saved: ${((1 - metrics.loadedSize / metrics.totalSize) * 100).toFixed(1)}%`);
}, 3000);
});
}
Common Mistakes
- Lazy loading above-the-fold images. The hero image and any image visible on initial load should load eagerly. Lazy loading them actually worsens LCP.
- Forgetting width and height attributes. Lazy loaded images without dimensions cause layout shifts. Always set width and height or use aspect-ratio CSS.
- Not providing a fallback for unsupported browsers. Older browsers don't support loading=lazy. Use Intersection Observer as a Polyfill.
- Lazy loading too aggressively. Everything deferred means nothing renders. Prioritize critical content (CSS, hero images, navigation).
- Not testing with slow connections. Lazy loading behaves differently on 3G vs WiFi. Test with throttled network conditions.
Practice Questions
- What problem does lazy loading solve for web performance?
- How does the native loading=lazy attribute work?
- What resources should NOT be lazy loaded?
- How do you measure the bandwidth savings from lazy loading?
- What happens when a browser doesn't support native lazy loading?
Challenge: Build a performance comparison page: load 20 images with and without lazy loading, measure page weight, load time, and Lighthouse scores for both versions, and present the results in a comparison table.
FAQ
Mini Project
Build a photo gallery with performance tracking: create a gallery page with 30 images, lazy load images using native loading=lazy, implement an Intersection Observer fallback, display real-time bandwidth savings, and benchmark against a non-lazy-loaded version.
What's Next
You understand lazy loading fundamentals. Now learn about the Native loading Attribute in depth.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro