Frontend Performance Optimization: Image Lazy Loading and WebP Format Optimization

Frontend Performance Optimization: Image Lazy Loading and WebP Format Optimization

Images are one of the main bottlenecks for web page loading performance. According to HTTP Archive data, images account for more than 50% of the total web page size on average. Optimizing image loading performance is crucial for improving page loading speed and user experience. This article introduces several commonly used image optimization techniques.

I. Image Format Selection

Choosing the right image format is the first step in optimization:

Format Features Compression Rate Browser Support Applicable Scenario
JPEG Lossy compression, supports progressive Medium All Photos, complex images
PNG Lossless compression, supports transparency Low All Icons, simple graphics
WebP Supports lossy/lossless, small size High Modern browsers General scenarios
AVIF Latest format, highest compression rate Very high Some browsers Cutting-edge projects
SVG Vector graphics, lossless scaling N/A All Icons, illustrations

II. WebP Format Optimization

WebP is an image format developed by Google, which can save approximately 25-35% of volume compared to JPEG and approximately 26% compared to PNG.

2.1 Using Tag

Use the picture tag to provide multiple formats, and the browser will automatically select the optimal supported format:

<picture>
  <source srcset="image.avif" type="image/avif">
  <source srcset="image.webp" type="image/webp">
  <img src="../image.jpg" alt="ๆ่ฟฐๆ–‡ๅญ—">
</picture>

2.2 Server-Side Conversion

Use server middleware to automatically convert image formats:

// Express middleware example
app.use('/images', (req, res, next) => {
  const accept = req.headers.accept || '';
  const ext = path.extname(req.path);
  
  if (accept.includes('image/avif') && ext === '.jpg') {
    req.url = req.url.replace('.jpg', '.avif');
  } else if (accept.includes('image/webp') && ext === '.jpg') {
    req.url = req.url.replace('.jpg', '.webp');
  }
  
  next();
});

๐Ÿ’ก Tip:WebP and AVIF compatibility is improving, with global support rate exceeding 95%. For older browsers, JPEG/PNG can be used as a fallback solution.

III. Responsive Images

Use srcset and sizes attributes to provide images of different sizes:

3.1 srcset Basic Usage

<img 
  src="../image-600.jpg" 
  srcset="image-300.jpg 300w,
          image-600.jpg 600w,
          image-1200.jpg 1200w"
  sizes="(max-width: 600px) 300px,
         (max-width: 1200px) 600px,
         1200px"
  alt="ๆ่ฟฐๆ–‡ๅญ—"
>

3.2 Using Picturefill Compatibility Solution

For older browsers that do not support srcset, the Picturefill library can be used:

<script src="https://cdnjs.cloudflare.com/ajax/libs/picturefill/3.0.3/picturefill.min.js"></script>

IV. Image Lazy Loading

Image lazy loading means loading images only when they enter the viewport, reducing initial page loading time.

4.1 Native Lazy Loading

Modern browsers support native lazy loading, just add the loading="lazy" attribute:

<img 
  src="../image.jpg" 
  alt="ๆ่ฟฐๆ–‡ๅญ—" 
  loading="lazy"
>

4.2 Custom Lazy Loading Implementation

For scenarios requiring more fine-grained control, custom implementation can be done:

class LazyLoad {
  constructor() {
    this.images = document.querySelectorAll('img[data-src]');
    this.observer = new IntersectionObserver(
      this.handleIntersection.bind(this),
      { threshold: 0.1, rootMargin: '100px' }
    );
    this.init();
  }
  
  init() {
    this.images.forEach(img => {
      this.observer.observe(img);
    });
  }
  
  handleIntersection(entries) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const img = entry.target;
        img.src = img.dataset.src;
        img.removeAttribute('data-src');
        this.observer.unobserve(img);
      }
    });
  }
}

// Initialize
document.addEventListener('DOMContentLoaded', () => {
  new LazyLoad();
});

4.3 Using Placeholder Images

Display placeholder images before the image is loaded to improve user experience:

<img 
  data-src="../image.jpg" 
  src="../placeholder.svg" 
  alt="ๆ่ฟฐๆ–‡ๅญ—"
  class="lazy-image"
>
.lazy-image {
  background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
  aspect-ratio: 16/9;
  object-fit: cover;
  transition: opacity 0.3s ease;
}

.lazy-image.loaded {
  background: transparent;
}

V. Image Compression and Optimization

5.1 Using Tools for Compression

  • Squoosh: Online compression tool developed by Google
  • TinyPNG: PNG/JPEG online compression
  • Sharp: Node.js image processing library
  • ImageOptim: Mac image compression tool

5.2 Automated Compression

Automatically compress images during the build process:

// Webpack configuration example
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif|webp)$/i,
        use: [
          {
            loader: 'image-webpack-loader',
            options: {
              webp: { quality: 80 },
              mozjpeg: { quality: 80 },
              pngquant: { quality: [0.6, 0.8] }
            }
          }
        ]
      }
    ]
  }
};

VI. CSS Optimization Tips

6.1 Using CSS Sprites

Combine multiple small icons into one image to reduce HTTP requests:

.icon {
  background-image: url('sprites.png');
  background-repeat: no-repeat;
}

.icon-home {
  background-position: 0 0;
  width: 32px;
  height: 32px;
}

.icon-search {
  background-position: -32px 0;
  width: 32px;
  height: 32px;
}

6.2 Using CSS Gradients Instead of Images

For simple background patterns, use CSS gradients instead of images:

.gradient-bg {
  background: linear-gradient(135deg, #10b981 0%, #06b6d4 100%);
}

.pattern-bg {
  background-image: 
    linear-gradient(45deg, rgba(255,255,255,0.05) 25%, transparent 25%),
    linear-gradient(-45deg, rgba(255,255,255,0.05) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, rgba(255,255,255,0.05) 75%),
    linear-gradient(-45deg, transparent 75%, rgba(255,255,255,0.05) 75%);
  background-size: 20px 20px;
}

VII. Server-Side Optimization

7.1 Using CDN

Use CDN to accelerate image loading, choose a CDN that supports automatic format conversion:

  • Cloudflare: Supports Polish automatic optimization
  • Cloudinary: Professional image CDN
  • Imgix: Supports real-time image processing

7.2 Configuring Cache Strategy

Set reasonable cache headers to reduce repeated requests:

# Nginx configuration example
location ~* \.(jpg|jpeg|png|gif|webp)$ {
  expires 1y;
  add_header Cache-Control "public, immutable";
  add_header Vary Accept;
}

7.3 Using HTTP/2 or HTTP/3

HTTP/2 supports multiplexing, allowing multiple images to be loaded simultaneously without blocking:

# Nginx HTTP/2 configuration
server {
  listen 443 ssl http2;
  # ... ๅ…ถไป–้…็ฝฎ
}

VIII. Performance Monitoring and Analysis

8.1 Using Lighthouse

Lighthouse provides detailed image optimization suggestions:

// Using CLI
lighthouse https://example.com --view

// Using Node.js
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');

async function runLighthouse(url) {
  const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
  const results = await lighthouse(url, { port: chrome.port });
  await chrome.kill();
  return results;
}

8.2 Using Web Vitals

Monitor core Web metrics:

import { getCLS, getFID, getLCP } from 'web-vitals';

getCLS(console.log);
getFID(console.log);
getLCP(console.log);

IX. Optimization Checklist

  • โœ… Use WebP/AVIF formats instead of JPEG/PNG
  • โœ… Implement image lazy loading
  • โœ… Use responsive images (srcset/sizes)
  • โœ… Compress images to appropriate quality
  • โœ… Set correct aspect ratio
  • โœ… Use CDN acceleration
  • โœ… Configure browser caching
  • โœ… Monitor performance metrics

X. Summary

Image optimization is an important part of frontend performance optimization. By choosing the right format, implementing lazy loading, and using responsive images, page loading time can be significantly reduced and user experience improved.

It is recommended to combine automated tools and monitoring systems to continuously optimize image performance. Remember, optimization is an ongoing process that requires continuous evaluation and adjustment.