Skip to main content

Image Optimization

Format selection, compression settings, dimensions, srcset, lazy loading, metadata—everything you need to know to serve images correctly.

Format Selection

Format is the highest-leverage decision in image optimization. Two images at identical visual quality can differ by 80% in file size purely because of format choice. Get this right before you touch anything else.

WebP

The default choice for web images. Lossy and lossless modes, alpha channel support, and universal browser coverage. If you're not using WebP, you're over-serving every visitor.

AVIF

Better compression than WebP, especially at low quality settings. Encode times are slower—worth it for high-traffic pages where the file will be downloaded millions of times.

JPEG XL

The most technically capable modern format. Lossless JPEG transcoding, excellent quality-to-size ratio. Browser support is still inconsistent—not ready as a default yet.

PNG

Lossless only. Right for logos, UI screenshots, and anything with hard edges or transparency that would artifact under lossy compression. Wrong for photos.

When to Use Each Format

SituationFormatWhy
Photo, hero image, blog imageWebPBest balance of quality, size, and support
High-traffic landing page heroAVIFExtra compression savings justify encode time
Logo, icon, UI screenshotPNG or SVGHard edges artifact badly under lossy compression
Transparent overlay or cutoutWebPAlpha channel support with lossy compression
Animated imageWebP or AVIFFar smaller than GIF; use video if longer than 3s
Vector illustration, icon, diagramSVGResolution-independent, scales to any size

Quality Settings That Actually Make Sense

Quality settings in lossy formats (WebP, JPEG, AVIF) work on a 0–100 scale, but the useful range is much narrower than that. Below ~60, compression artifacts become visible. Above ~90, file sizes climb steeply with no perceptible quality gain.

The practical ranges by use case:

Use CaseWebP QualityNotes
General web images80–85Indistinguishable from source at normal viewing
Hero / full-bleed images85–90Larger display size warrants slightly higher quality
Thumbnails70–80Small display size hides compression well
Product images (e-commerce)85–90Quality affects perceived product value

85 is a safe default for almost everything. The difference between 85 and 95 is rarely visible; the difference in file size is significant.

Dimensions and Responsive Images

Format and quality handle compression. Dimensions handle the other half of the problem—serving the right number of pixels to begin with.

The Dimensions Problem

A 4000×3000px image displayed at 800×600px on screen has 25 times more pixels than the browser will ever render. Every one of those extra pixels was downloaded, decoded, and thrown away. The browser cannot optimize this for you—it downloads the full file before it knows the display size.

Resize images to the largest size they'll be displayed at before uploading. For a blog post with a max content width of 800px, your images should be 800px wide—not 1600px, not original camera resolution. For retina displays (2x), 1600px makes sense. Going beyond that for a fixed-width content column doesn't.

srcset: Letting the Browser Choose

For responsive layouts where the same image slot renders at different widths on different devices, srcset lets you provide multiple image sizes and let the browser pick the most appropriate one based on the viewport and device pixel ratio.

<img
  src="photo-800.webp"
  srcset="
    photo-400.webp  400w,
    photo-800.webp  800w,
    photo-1200.webp 1200w
  "
  sizes="(max-width: 600px) 100vw, 800px"
  alt="[Description of image]"
  loading="lazy"
  width="800"
  height="600"
/>

The sizes attribute tells the browser how wide the image will actually be displayed—not the viewport width. A browser on a 1200px viewport loading an image inside an 800px content column should know it only needs the 800px file, not the 1200px one.

Always include explicit width and height attributes. Without them, the browser doesn't know the aspect ratio until the image loads, which causes layout shift—a direct hit to your Cumulative Layout Shift score.

The picture Element for Format Fallbacks

If you need to serve AVIF to browsers that support it and fall back to WebP for those that don't, use <picture>:

<picture>
  <source srcset="photo.avif" type="image/avif" />
  <source srcset="photo.webp" type="image/webp" />
  <img src="photo.jpg" alt="[Description of image]" loading="lazy" width="800" height="600" />
</picture>

The browser uses the first <source> it supports and falls back to the <img> tag. JPEG as the final fallback means even IE11 gets something—not that you probably care, but it costs nothing.

Loading Behavior, Metadata, and Alt Text

loading="lazy" and loading="eager"

loading="lazy" defers image download until the image is close to the viewport. It's a one-attribute change that can cut initial page load time significantly on image-heavy pages. Add it to every image that isn't visible on first load.

The exception is above-the-fold images—your hero, your logo, anything visible before the user scrolls. Those should be loading="eager" (or no attribute at all, since eager is the default). Lazy-loading above-the-fold images delays the Largest Contentful Paint and actively hurts your score.

fetchpriority="high"

For your single most important above-the-fold image—typically the hero—add fetchpriority="high". This hints to the browser that this image should be prioritized in the network queue. It's particularly effective when the image is your LCP element. Only use it on one image per page; applying it broadly defeats the purpose.

Strip Metadata

Camera images contain EXIF metadata—GPS coordinates, camera model, shooting settings, timestamps. This data is invisible to visitors but adds kilobytes to every file. XnConvert strips it by default when converting. If you're processing images another way, make sure metadata stripping is enabled. There's no reason to serve a visitor the GPS coordinates of where you took a photo.

Alt Text and File Names

Alt text serves two purposes: accessibility (screen readers read it aloud) and SEO (it's the primary signal Google uses to understand image content). It should describe what's in the image specifically—not keyword-stuffed, not empty, not "image of."

❌ Bad

alt="image"
alt="photo of office"
alt="Vancouver web developer web development Vancouver SEO"

✅ Good

alt="Standing desk setup with dual monitors in a home office"
alt="XnConvert Output tab showing WebP format selected at quality 85"

File names follow the same principle. standing-desk-home-office.webp gives Google useful context before it even looks at the image. IMG_4872.webp gives it nothing.

Use hyphens, not underscores. Google treats hyphens as word separators and underscores as connectors—red-office-chair reads as three separate words, red_office_chair reads as one.

How to Optimize Images with XnConvert

XnConvert is a free, cross-platform batch image converter—Windows, Mac, and Linux. I've used it for over two years and hold a commercial license. It handles an enormous range of formats out of the box with sensible defaults, and the GUI makes it accessible without requiring a build pipeline or command-line setup.

The interface isn't immediately obvious the first time you open it. Here's exactly what to do.

Step 1: Download and Install

Download from xnview.com/en/xnconvert. Free for personal use, paid license required for commercial use. Install normally—no account required.

The XnConvert download page on xnview.com/en/xnconvert

Step 2: Understand the Three-Tab Workflow

Input → Actions → Output

XnConvert has three tabs at the top left: Input, Actions, and Output. You work left to right. This isn't optional—if you configure Output before adding files on Input, nothing will happen and XnConvert won't explain why.

Think of it as a pipeline: Input defines what goes in, Actions defines what transformations to apply, Output defines what comes out and where.

The XnConvert input page with no files selected. The three tabs (Input, Actions, Output) are highlighted on the top left of the application.

Step 3: Add Your Images

Input tab

On the Input tab, click Add files… for individual images or Add folder… for a directory. Drag and drop also works. XnConvert lists each file with its filename, dimensions, file size, and format—useful for immediately seeing which files are oversized. In this example I'm adding three JPG files to convert to WebP.

You're not limited to one folder at a time. You can pull in files from multiple locations on your computer in a single session—add one folder, then another, then individual files from somewhere else entirely. XnConvert holds everything as a single list in memory and processes it all in one pass.

The Remove and Remove All buttons below the file list only affect this in-memory queue—they don't delete anything from your computer. If you added the wrong files or want to start over, Remove All clears the list without touching your originals.

Check Subfolders below the file list if you want to include images nested inside subdirectories. The file count updates as XnConvert scans.

The XnConvert input page with 3 images selected from multiple folders.

Step 4: Add a Resize Action

Actions tab — optional but usually necessary

Click the Actions tab. Click Add action…TransformResize.

The XnConvert Actions page with no actions selected. A red circle highlights the Add Action button.The Add Action menu open in XnConvert, with the Transform sub-menu expanded showing the Resize option.

Set width to your maximum display width—in this example, 800px. Set the resize type to Width. For the Enlarge/Reduce mode, use Reduce only unless you know every image in your batch is already wider than the target—if any image is smaller, Always will upscale it, which increases file size and degrades quality. 1200px is a safe ceiling for most blog layouts; 800px works well for content images in a narrower column.

You can stack multiple actions here—resize, then adjust levels, then strip metadata. They execute in order top to bottom.

The XnConvert Actions page with the resize mode set to Width and the width set to 800 pixels.

Step 5: Set Format and Quality

Output tab

Click the Output tab. The Format dropdown defaults to "Keep original format"—change it to WebP. Once WebP is selected, a settings icon appears next to the dropdown. Click it and set quality to 80. For general content images like these three JPGs, 80 hits the sweet spot—files come out significantly smaller than the originals with no major visible difference at normal screen sizes.

The XnConvert Output tab showing the Format dropdown on the right side set to WebP.The XnConvert Output tab with the quality settings dialog open, accessed by clicking the settings button next to the Format dropdown.

For the output location, select Set a specific folder and point it somewhere you'll recognize. Once your files are converted they'll carry whatever filename they had, just with a .webp extension, as long as the Preserve Extension option is not checked. This is also a good time to properly name your files, but don't worry, I'll remind you again later. Never overwrite your originals. You will eventually need one of them.

The XnConvert output folder settings. A custom output folder helps with organization. The filename field supports the {Filename} variable to reuse the original filename without its extension.

Step 6: Convert and Check the Results

Output tab → Convert button

Click Convert. XnConvert processes the list, applies Actions in order, and writes to the Output folder. Three images typically takes under a second.

The XnConvert Convert button at the bottom of the Output tab.

When it finishes, XnConvert shows a Status screen inside the app with the full results—you don't need to go hunting in Explorer to see what happened. Each file is listed with its source path, output path, original size, converted size, and the percentage reduction. At the bottom you get totals across all files.

The XnConvert Status screen showing three images converted from megabyte-sized JPGs to kilobyte-sized WebP files, with reductions reaching 99%.

6.46 MB in, 141 KB out, in one second. The headshot alone went from 4.33 MB to 41 KB—a 99% reduction with no major visible quality difference at normal screen sizes. This is why format conversion matters more than any other optimization step. Once you've confirmed quality looks right, your files are ready—make sure they're properly named before uploading to your web server.

Windows 10 File Explorer showing three properly named WebP images ready to upload to a web server.

Thinking About Your Own Site?

Image optimization is part of every project I take on—not an add-on, just how the work gets done.

Get in Touch