UXR SEO Analyzer documentation

Detailed guide

Image Optimization

View contents

Introduction

Images are often the largest resources on a webpage, accounting for 40-60% of total page weight on most websites. Unoptimized images directly impact Core Web Vitals—particularly LCP (Largest Contentful Paint), which measures how quickly your largest content element loads.

Understanding image optimization is essential not only for performance but also for SEO, as Google uses page speed as a ranking factor and image search can drive significant organic traffic.

Why Image Optimization Matters

When a browser loads a webpage, images compete with other resources for bandwidth. Large, unoptimized images cause several problems:

Image Impact on Page Load:
┌─────────────────────────────────────────────────────────────┐
│ Unoptimized Images                                          │
│ ├── Slower LCP (largest image takes longer to load)        │
│ ├── Higher bandwidth usage (costs for users on mobile)     │
│ ├── Longer Time to Interactive (competing resources)       │
│ └── Poor user experience (especially on slow connections)  │
│                                                             │
│ Optimized Images                                            │
│ ├── Faster LCP (smaller file sizes)                        │
│ ├── Better Core Web Vitals scores                          │
│ ├── Improved mobile experience                              │
│ └── Lower server costs (less bandwidth)                    │
└─────────────────────────────────────────────────────────────┘

Impact on Core Web Vitals

Metric How Images Affect It
LCP Hero images are often the LCP element—large images delay LCP
CLS Images without dimensions cause layout shifts when they load
INP Large images can block the main thread during decode

Key Image Optimization Concepts

1. Modern Image Formats

Not all image formats are created equal. Modern formats offer significantly better compression:

Format Best For Compression Browser Support
WebP Photos, graphics 25-35% smaller than JPEG 97%+ browsers
AVIF Photos, HDR 50% smaller than JPEG 85%+ browsers
JPEG Photos (fallback) Good, but dated Universal
PNG Transparency, graphics Lossless, larger files Universal
SVG Icons, logos, illustrations Scalable, tiny files Universal

2. Responsive Images

Different devices need different image sizes. A 2000px hero image is wasteful on a 375px mobile screen:

<!-- Responsive images with srcset -->
<img
  src="hero-800.jpg"
  srcset="hero-400.jpg 400w,
          hero-800.jpg 800w,
          hero-1200.jpg 1200w"
  sizes="(max-width: 600px) 400px,
         (max-width: 1200px) 800px,
         1200px"
  alt="Descriptive alt text"
>

The browser automatically selects the appropriate image size based on screen width and device pixel ratio.

3. Lazy Loading

Images below the fold don’t need to load immediately. Native lazy loading defers their loading until the user scrolls near them:

<!-- Native lazy loading -->
<img src="image.jpg" loading="lazy" alt="Description">

<!-- Critical images should NOT be lazy loaded -->
<img src="hero.jpg" alt="Hero image" fetchpriority="high">

4. Proper Image Dimensions

Always specify width and height to prevent Cumulative Layout Shift (CLS):

<!-- ✅ Good: Dimensions specified -->
<img src="photo.jpg" width="800" height="600" alt="Photo">

<!-- ❌ Bad: No dimensions (causes CLS) -->
<img src="photo.jpg" alt="Photo">

Image SEO Basics

Optimized images also improve your visibility in image search:

File Naming

❌ Bad:  IMG_20231015_143022.jpg
❌ Bad:  image1.jpg

✅ Good: blue-running-shoes-side-view.jpg
✅ Good: ux-research-interview-session.jpg

Alt Text

Alt text serves two purposes: accessibility and SEO.

<!-- ❌ Bad: Empty or keyword-stuffed -->
<img src="shoes.jpg" alt="">
<img src="shoes.jpg" alt="shoes buy shoes cheap shoes running shoes">

<!-- ✅ Good: Descriptive and natural -->
<img src="shoes.jpg" alt="Blue Nike running shoes with white sole">

Image Sitemaps

For important images, include them in your sitemap or create a dedicated image sitemap:

<url>
  <loc>https://example.com/page</loc>
  <image:image>
    <image:loc>https://example.com/images/photo.jpg</image:loc>
    <image:caption>Description of the image</image:caption>
  </image:image>
</url>

Common Image Problems

Problem 1: Oversized Images

Issue: Uploading a 4000x3000px image when it’s displayed at 800x600px.

Solution: Resize images to their maximum display size (or use responsive images).

Problem 2: Wrong Format

Issue: Using PNG for photographs (huge file sizes).

Solution: Use WebP or AVIF for photos, PNG only for transparency, SVG for icons.

Problem 3: No Compression

Issue: Uploading images straight from the camera.

Solution: Compress images with tools like Squoosh, ImageOptim, or Sharp.

Problem 4: Missing Lazy Loading

Issue: All images load immediately, blocking critical resources.

Solution: Add loading="lazy" to below-fold images.

Measuring Image Performance

Using Lighthouse

  1. Open Chrome DevTools (F12)
  2. Go to Lighthouse tab
  3. Run a Performance audit
  4. Look for image-related recommendations:
    • “Properly size images”
    • “Serve images in next-gen formats”
    • “Efficiently encode images”
    • “Defer offscreen images”

Using Network Panel

  1. Open DevTools → Network tab
  2. Filter by “Img”
  3. Check file sizes and load times
  4. Look for images larger than 100KB

Implementation

Strategy 1: Choose the Right Image Format

Modern Formats Comparison

Format Selection Decision Tree:
┌─────────────────────────────────────────────────────────────┐
│ Is it a photograph or complex image?                        │
│ ├── YES                                                     │
│ │   └── Use AVIF (primary) → WebP (fallback) → JPEG        │
│ │                                                           │
│ └── NO (icon, logo, illustration)                          │
│     ├── Does it need animation?                            │
│     │   ├── YES → Use animated WebP or video               │
│     │   └── NO                                             │
│     │       ├── Is it scalable vector art?                 │
│     │       │   ├── YES → Use SVG                          │
│     │       │   └── NO → Use PNG or WebP                   │
│     └── Does it need transparency?                         │
│         ├── YES → Use WebP or PNG                          │
│         └── NO → Use WebP or JPEG                          │
└─────────────────────────────────────────────────────────────┘

Implementing Progressive Enhancement with Picture

<picture>
  <!-- AVIF: Best compression, growing support -->
  <source
    srcset="image.avif"
    type="image/avif"
  >
  <!-- WebP: Good compression, excellent support -->
  <source
    srcset="image.webp"
    type="image/webp"
  >
  <!-- JPEG: Universal fallback -->
  <img
    src="image.jpg"
    alt="Descriptive alt text"
    width="800"
    height="600"
    loading="lazy"
  >
</picture>

Format Compression Comparison

Format Photo (1000x800) Compression Quality
Original JPEG 450 KB - 100%
Optimized JPEG (q85) 180 KB 60% smaller 95%
WebP (q85) 120 KB 73% smaller 95%
AVIF (q80) 75 KB 83% smaller 95%

Strategy 2: Implement Responsive Images

Using srcset and sizes

<img
  src="hero-800.jpg"
  srcset="
    hero-400.jpg 400w,
    hero-600.jpg 600w,
    hero-800.jpg 800w,
    hero-1200.jpg 1200w,
    hero-1600.jpg 1600w
  "
  sizes="
    (max-width: 400px) 100vw,
    (max-width: 800px) 100vw,
    (max-width: 1200px) 80vw,
    1200px
  "
  alt="Hero image description"
  width="1600"
  height="900"
>

Understanding sizes Attribute

sizes Calculation Examples:
┌─────────────────────────────────────────────────────────────┐
│ sizes="(max-width: 600px) 100vw, 50vw"                      │
│                                                             │
│ On 400px viewport:                                          │
│ → Image width = 100vw = 400px                               │
│ → Browser selects 400w image                                │
│                                                             │
│ On 1200px viewport:                                         │
│ → Image width = 50vw = 600px                                │
│ → Browser selects 600w or 800w image (depends on DPR)       │
│                                                             │
│ On 1200px viewport with 2x DPR (Retina):                    │
│ → Image width = 50vw = 600px × 2 = 1200px effective         │
│ → Browser selects 1200w image                               │
└─────────────────────────────────────────────────────────────┘

Art Direction with Picture Element

Use <picture> when you need different crops for different screen sizes:

<picture>
  <!-- Mobile: Square crop, centered on subject -->
  <source
    media="(max-width: 600px)"
    srcset="product-mobile.webp"
    type="image/webp"
  >
  <source
    media="(max-width: 600px)"
    srcset="product-mobile.jpg"
  >

  <!-- Desktop: Wide landscape crop -->
  <source
    srcset="product-desktop.webp"
    type="image/webp"
  >
  <img
    src="product-desktop.jpg"
    alt="Product name - detailed view"
    width="1200"
    height="600"
  >
</picture>

Strategy 3: Optimize Loading Priority

Fetchpriority for Critical Images

<!-- LCP image: Load with highest priority -->
<img
  src="hero.webp"
  alt="Hero image"
  fetchpriority="high"
  decoding="async"
  width="1200"
  height="600"
>

<!-- Below-fold images: Lower priority, lazy load -->
<img
  src="gallery-1.webp"
  alt="Gallery image 1"
  loading="lazy"
  decoding="async"
  width="400"
  height="300"
>

Preloading Critical Images

<head>
  <!-- Preload LCP image with format hints -->
  <link
    rel="preload"
    as="image"
    href="hero.webp"
    type="image/webp"
    fetchpriority="high"
  >

  <!-- Preload responsive image -->
  <link
    rel="preload"
    as="image"
    href="hero-1200.webp"
    imagesrcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
    imagesizes="(max-width: 600px) 100vw, 1200px"
  >
</head>

Lazy Loading Best Practices

<!-- ❌ Wrong: Lazy loading LCP/above-fold images -->
<img src="hero.jpg" loading="lazy" alt="Hero">

<!-- ✅ Correct: Only lazy load below-fold images -->
<img src="hero.jpg" fetchpriority="high" alt="Hero">

<section class="below-fold">
  <img src="product-1.jpg" loading="lazy" alt="Product 1">
  <img src="product-2.jpg" loading="lazy" alt="Product 2">
</section>

Strategy 4: Compression and Quality

Compression Tool Comparison

Tool Type Best For Quality Control
Squoosh Web app Manual optimization, testing Visual comparison
Sharp Node.js Build pipelines, automation Numeric quality
ImageOptim Desktop (Mac) Batch optimization Automatic
svgo CLI SVG optimization Size reduction

Build Pipeline Integration

// Sharp example for Node.js build
const sharp = require('sharp');

async function optimizeImage(inputPath, outputPath) {
  await sharp(inputPath)
    // Resize to max dimensions
    .resize(1600, 900, {
      fit: 'inside',
      withoutEnlargement: true
    })
    // Output as WebP
    .webp({
      quality: 85,
      effort: 6
    })
    .toFile(outputPath.replace(/\.\w+$/, '.webp'));

  // Also create AVIF version
  await sharp(inputPath)
    .resize(1600, 900, {
      fit: 'inside',
      withoutEnlargement: true
    })
    .avif({
      quality: 80,
      effort: 6
    })
    .toFile(outputPath.replace(/\.\w+$/, '.avif'));
}

Quality Guidelines

Quality Settings by Use Case:
┌─────────────────────────────────────────────────────────────┐
│ Use Case              │ JPEG/WebP │ AVIF  │ Notes           │
│───────────────────────│───────────│───────│─────────────────│
│ Hero images           │ 85-90     │ 80-85 │ High quality    │
│ Product photos        │ 85        │ 80    │ Detail matters  │
│ Blog thumbnails       │ 75-80     │ 70-75 │ Can be lower    │
│ Background patterns   │ 60-70     │ 55-65 │ Lower priority  │
│ Icons/logos (WebP)    │ 90-100    │ -     │ Keep crisp      │
└─────────────────────────────────────────────────────────────┘

Strategy 5: Prevent Layout Shift

Always Include Dimensions

<!-- ✅ Correct: Explicit dimensions -->
<img
  src="product.jpg"
  width="400"
  height="300"
  alt="Product"
>

<!-- ✅ Also correct: CSS aspect-ratio -->
<style>
  .product-image {
    aspect-ratio: 4/3;
    width: 100%;
    height: auto;
  }
</style>
<img src="product.jpg" class="product-image" alt="Product">

Container-Based Sizing

<div class="image-container">
  <img
    src="image.jpg"
    alt="Description"
    loading="lazy"
  >
</div>

<style>
.image-container {
  position: relative;
  padding-bottom: 56.25%; /* 16:9 aspect ratio */
  height: 0;
  overflow: hidden;
}

.image-container img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
</style>

Strategy 6: Image CDN and Optimization Services

Benefits of Image CDNs

  1. Automatic format conversion - Serve WebP/AVIF based on browser support
  2. On-the-fly resizing - Generate responsive sizes dynamically
  3. Global edge caching - Faster delivery worldwide
  4. URL-based transformations - No build step required

Example: Cloudinary URL Transformations

<!-- Original -->
<img src="https://res.cloudinary.com/demo/image/upload/sample.jpg">

<!-- Optimized: Auto format, quality, and size -->
<img src="https://res.cloudinary.com/demo/image/upload/
  f_auto,
  q_auto,
  w_800,
  c_limit
  /sample.jpg">

<!-- Responsive with srcset -->
<img
  src="https://res.cloudinary.com/demo/image/upload/f_auto,q_auto,w_800/sample.jpg"
  srcset="
    https://res.cloudinary.com/demo/image/upload/f_auto,q_auto,w_400/sample.jpg 400w,
    https://res.cloudinary.com/demo/image/upload/f_auto,q_auto,w_800/sample.jpg 800w,
    https://res.cloudinary.com/demo/image/upload/f_auto,q_auto,w_1200/sample.jpg 1200w
  "
  sizes="(max-width: 600px) 100vw, 800px"
  alt="Sample image"
>

Strategy 7: SVG Optimization

SVGO Configuration

// svgo.config.js
module.exports = {
  plugins: [
    'removeDoctype',
    'removeXMLProcInst',
    'removeComments',
    'removeMetadata',
    'removeEditorsNSData',
    'cleanupAttrs',
    'mergeStyles',
    'inlineStyles',
    'minifyStyles',
    'cleanupIds',
    'removeUselessDefs',
    'removeUselessStrokeAndFill',
    'removeHiddenElems',
    'removeEmptyText',
    'removeEmptyAttrs',
    'removeEmptyContainers',
    'convertPathData',
    'mergePaths',
    {
      name: 'removeViewBox',
      active: false  // Keep viewBox for responsive scaling
    }
  ]
};

Inline SVG Best Practices

<!-- For icons used multiple times: use sprite -->
<svg style="display: none;">
  <symbol id="icon-search" viewBox="0 0 24 24">
    <path d="..."/>
  </symbol>
  <symbol id="icon-menu" viewBox="0 0 24 24">
    <path d="..."/>
  </symbol>
</svg>

<!-- Usage -->
<svg aria-label="Search"><use href="#icon-search"/></svg>
<svg aria-label="Menu"><use href="#icon-menu"/></svg>

Measuring Improvements

Before/After Comparison

BEFORE Optimization:
├── Total image weight: 2.8 MB
├── LCP: 4.2s
├── Number of images: 15
├── Lighthouse Image Score: 45
└── CLS (image-related): 0.15

AFTER Optimization:
├── Total image weight: 450 KB (↓84%)
├── LCP: 1.8s (↓57%)
├── Number of images: 15 (same)
├── Lighthouse Image Score: 100
└── CLS (image-related): 0 (↓100%)

Lighthouse Audits to Check

  • “Properly size images” - Serving correct dimensions
  • “Serve images in next-gen formats” - WebP/AVIF usage
  • “Efficiently encode images” - Compression applied
  • “Defer offscreen images” - Lazy loading implemented
  • “Image elements have explicit width and height” - CLS prevention

Optimization Checklist

Before deploying, verify:

  • [ ] Hero/LCP images use fetchpriority="high"
  • [ ] Below-fold images use loading="lazy"
  • [ ] All images have width and height attributes
  • [ ] WebP (or AVIF) versions available with fallbacks
  • [ ] srcset implemented for responsive images
  • [ ] sizes attribute accurately reflects layout
  • [ ] Images compressed to appropriate quality
  • [ ] SVGs optimized with SVGO
  • [ ] Alt text is descriptive and unique
  • [ ] File names are descriptive and SEO-friendly

Learn more about optimizing your site’s images:

📚 Back to Performance SEO Hub - Explore all performance topics


References

  1. MDN Web Docs - Responsive Images
  2. Ahrefs - Image SEO: 12 Actionable Tips
  3. web.dev - Optimize Images
  4. Chrome Developers - Efficiently Encode Images

Try It Yourself

Want to check your site’s image optimization?

🔧 Download UXR SEO Analyzer (Free, 100% local analysis)


Disclaimer: The analyzers in this extension are reference guides based on official documentation from MDN, web.dev, and industry best practices. They do not represent absolute truths about how search engines evaluate your content—only search engines know their internal algorithms. Use these recommendations as a starting point to improve your site.

Last updated: December 14, 2025

Related articles

Category hub

Hub

Performance SEO Hub

Performance is a critical ranking factor and directly impacts user experience

In the same category

Detailed guide

Complete LCP Optimization Guide

Largest Contentful Paint (LCP) measures when the largest content element becomes visible to users

Introduction

CLS (Cumulative Layout Shift)

Cumulative Layout Shift (CLS) is one of Google's Core Web Vitals—a set of metrics that measure real-world user experience on your website

Introduction

Render-Blocking Resources

Render-blocking resources are files that prevent the browser from displaying content to users until they are fully downloaded and processed

Last updated: