Why Image Lazy Loading Matters
Images are among the largest resource types on web pages. According to HTTP Archive statistics, images account for over 50% of the average webpage's total weight. On a typical news or e-commerce page, dozens of images may load simultaneously, significantly increasing initial page load time, wasting bandwidth, and consuming data. The core idea of image lazy loading is: only load images within the user's current visible area (viewport), deferring other images until the user scrolls near them. This approach dramatically reduces initial page load time, improving user experience and Core Web Vitals.
1. Technical Overview
1.1 How It Works
Lazy loading is implemented through the following key steps:
- Replace Image Source: In HTML, replace the
<img>tag'ssrcattribute with a placeholder or blank, storing the real image URL in a custom attribute likedata-src - Monitor Scroll Position: Listen for page scroll events or use the Intersection Observer API to detect when images enter the viewport
- Load Real Image: When an image enters the viewport, assign
data-srcvalue to thesrcattribute, triggering the browser to load - Handle Load Completion: After the image loads, remove placeholder styles and display the real image
1.2 Performance Benefits
| Scenario | Without Lazy Loading | With Lazy Loading | Improvement |
|---|---|---|---|
| Initial Page Load Time | 3.5s | 1.8s | 48% improvement |
| Total Page Transfer Size | 2.8MB | 0.6MB | 78% reduction |
| Lighthouse Performance Score | 62 | 94 | 32-point improvement |
2. Implementation Approaches
2.1 Native Lazy Loading (Recommended)
Starting from Chrome 76, browsers natively support image lazy loading — just add the loading="lazy" attribute to <img> tags:
<img src="example.jpg" loading="lazy" alt="Example image" />
<!-- Also supports iframe lazy loading -->
<iframe src="example.html" loading="lazy"></iframe>
Advantages: Zero JavaScript code, browser automatically optimizes load timing, best performance.
Disadvantages: Not supported by all browsers (Safari 15.4+ required).
2.2 Intersection Observer API
For scenarios needing more control, use the Intersection Observer API:
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy');
observer.unobserve(img);
}
});
});
document.querySelectorAll('img.lazy').forEach(img => {
imageObserver.observe(img);
});
| Approach | Complexity | Performance | Maintainability | Use Case |
|---|---|---|---|---|
| Native lazy attribute | Low | Excellent | High | General scenarios |
| Intersection Observer | Medium | High | Medium | Custom loading effects needed |
| Third-party JS library | Low | Medium | Medium | Legacy browser compatibility |
2.3 Third-Party Libraries
- Lozad.js: Lightweight (1KB), Intersection Observer based
- lazysizes: Most feature-rich, supports responsive images and auto-calculation
- vanilla-lazyload: Simple and easy, supports images, iframes, and video
3. Advanced Optimization Techniques
// Combining with placeholder technique (BlurHash)
const img = new Image();
img.onload = () => {
// First show blurred thumbnail
placeholder.style.filter = 'blur(20px)';
// Fade in high-res image after load
highResImg.classList.add('loaded');
};
img.src = highResUrl;
4. Important Considerations
- Above-fold images should not use lazy loading: Images in the initial viewport should load normally
- Reserve image placeholder space: Set aspect-ratio to prevent layout shifts
- Consider SEO impact: Ensure search engine crawlers can access images
- Compatibility handling: Provide fallback for browsers without native lazy loading
- Image decoding optimization: Use
decoding="async"attribute for async image decoding
5. Summary
Image lazy loading is one of the simplest and most effective techniques for improving web performance. For modern browsers, directly using the loading="lazy" attribute is recommended. For custom loading effects or additional functionality, the Intersection Observer API provides sufficient flexibility and performance. Regardless of the approach, properly configured lazy loading significantly improves user experience and core performance metrics.