Image Optimization for Web: The Real Checklist (2026 Edition)
Images are usually 60 to 80 percent of a web page's total weight. Optimize them well and your site loads twice as fast. Optimize them badly and nothing else you do matters, because the browser is still downloading 3 MB of JPEGs before it can render anything.
I've audited hundreds of small business websites in the last year. The pattern is almost always the same: unoptimized hero images, no responsive srcset, no lazy loading, no modern formats, and alt text that's either missing or stuffed with keywords. Each of those costs you Lighthouse points, SEO rankings, and conversions.
Here is the actual checklist I run through for every client site. Ten items, in order of impact, with the code you need to ship each one.
1. Use WebP or AVIF, Not JPEG or PNG
If your site is serving images as JPEG or PNG in 2026, you're shipping files 30 to 50 percent larger than they need to be. WebP has been supported by every modern browser since 2020. AVIF has been supported since 2023. There's no reason not to use them.
Size comparison on a typical hero image: - PNG: 1.4 MB - JPEG (quality 80): 380 KB - WebP (quality 80): 190 KB - AVIF (quality 60): 110 KB
Same visual quality. Less than a tenth the file size if you go from PNG to AVIF.
How to convert: If you're on Next.js, the `<Image>` component handles this automatically. It serves WebP or AVIF based on the browser's Accept header. If you're on plain HTML, use `<picture>`:
```html <picture> <source srcset="/hero.avif" type="image/avif"> <source srcset="/hero.webp" type="image/webp"> <img src="/hero.jpg" alt="Main hero image" width="1200" height="600"> </picture> ```
Browsers pick the best format they support. If you're converting manually, use `cwebp` or `avifenc` from the command line, or a tool like Squoosh for one-offs.
2. Always Use the sizes Attribute
This one is the single biggest cause of unnecessary image downloads on mobile. Without a `sizes` attribute, the browser doesn't know how wide the image will display, so it downloads the largest file in the srcset just to be safe.
Say you have a hero image with a srcset of 640w, 1024w, and 1920w. On a phone displaying the image at 375px wide, without `sizes`, the browser might download the 1920w version. That's 3x the data for no visible benefit.
With Next.js:
```tsx <Image src="/hero.webp" alt="Hero" width={1920} height={1080} sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 1200px" /> ```
With plain HTML:
```html <img src="/hero-1200.webp" srcset="/hero-640.webp 640w, /hero-1024.webp 1024w, /hero-1920.webp 1920w" sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 1200px" alt="Hero" width="1200" height="600" > ```
The `sizes` attribute tells the browser: on screens up to 768px, this image displays at 100% of viewport width. On screens up to 1200px, it displays at 50% width. Otherwise, it's 1200px wide. The browser then picks the smallest srcset candidate that still looks sharp.
3. Prevent CLS by Setting width and height
Cumulative Layout Shift (CLS) is one of Google's Core Web Vitals. It happens when content jumps around as the page loads. The number one cause? Images without width and height attributes. The browser doesn't know how much space to reserve, so content below the image shifts when it finally loads.
Every image needs width and height. Not CSS width and height. HTML attributes.
```html <img src="/photo.webp" width="800" height="600" alt="..."> ```
Modern browsers use these to calculate aspect ratio and reserve the right amount of space before the image loads. No layout shift. No content jumping.
Next.js `<Image>` requires width and height by default, so this one is easy if you're on the framework. On plain HTML, audit every `<img>` tag.
4. Lazy Load Everything Below the Fold
The hero image should load immediately. Every other image should load only when the user is about to see it. Browsers have native lazy loading built in now, no JavaScript needed.
```html <img src="/product.webp" loading="lazy" width="400" height="400" alt="Product"> ```
For the hero (or whatever is above the fold), do the opposite:
```html <img src="/hero.webp" loading="eager" fetchpriority="high" width="1200" height="600" alt="Hero"> ```
`fetchpriority="high"` is newer. It tells the browser to prioritize this resource in the network queue. Combined with `loading="eager"`, your LCP element gets served first.
In Next.js, use the `priority` prop on the above-fold image and leave everything else at the default (which is lazy).
```tsx <Image src="/hero.webp" priority ... /> <Image src="/about.webp" ... /> // lazy by default ```
5. Serve Responsive Images With srcset
Generate multiple sizes of the same image and let the browser pick. A typical set: 640w, 1024w, 1920w. That covers small phones, tablets, and desktops without shipping 4K images to 5-inch screens.
Next.js does this automatically. On other stacks, tools like Sharp (Node), `cwebp`, or cloud services like Cloudinary and Imgix handle batch resizing. Build it into your image pipeline so you never ship a single fixed-size image again.
6. Alt Text: For SEO AND Accessibility
Alt text does two jobs. It tells screen readers what the image shows, and it gives Google context about what the image is. Good alt text does both without keyword stuffing.
Good alt text: - "Chef plating a margherita pizza at Giuseppe's restaurant in Las Cruces" - "Annual revenue chart showing 40% growth year over year" - "Blue leather office chair with lumbar support"
Bad alt text: - "Image123.jpg" - "pizza pizza italian pizza restaurant las cruces best pizza" - Empty or missing
If the image is decorative (a background pattern, a divider, an icon next to text that repeats the label), use `alt=""`. Screen readers skip it. Google ignores it. That's what you want.
If the image conveys information, describe it naturally in the alt text. Include a keyword if it fits the sentence. Don't force it.
7. Use a CDN Image Pipeline
Hosting images on your origin server is fine until you have traffic. Once traffic scales, every image request hits your server. A CDN image pipeline caches images at the edge and serves them from the nearest location to the user.
Options:
- Cloudflare Images: $5/mo for 100K images, 100K deliveries/mo. Handles resizing, format conversion, and caching. - Cloudinary: Free tier up to 25 GB storage and 25 GB bandwidth. Generous for small sites. - Imgix: Pay-as-you-go. Best for high-traffic sites. - AWS CloudFront + S3 + Lambda@Edge: Cheap at scale but requires setup. - Vercel Image Optimization: Built into Next.js on Vercel. Handles everything automatically.
If you're on AWS Amplify (like we are), it uses CloudFront under the hood. Next.js image optimization works out of the box, though you need to configure the `images.remotePatterns` array in `next.config.js` if you're pulling from external sources.
8. Compress Before Upload
CDN image pipelines are great, but you should still compress source images before they go into your pipeline. A 10 MB source image takes longer for your CDN to process on first request, which hurts the user who triggers that processing.
Quick tools: - Squoosh (squoosh.app): Drag and drop a single image, pick a format and quality, download. Free. - TinyPNG: Batch compression for PNG and JPEG. Free for up to 20 images. - ImageOptim (macOS): Drop a folder, it compresses everything in place. - Sharp (Node): If you want to automate compression in your build pipeline.
Rule of thumb: hero images under 200 KB, body images under 100 KB, thumbnails under 20 KB. If any image is over 500 KB after compression, something's wrong.
9. Use SVG for Logos, Icons, and Simple Graphics
SVG is vector. It scales to any size without getting blurry. It's tiny (usually under 5 KB). And it's indexable by Google.
Every logo on your site should be an SVG. Every icon should be an SVG or an icon font. Every chart or diagram that's just shapes and text should be an SVG.
The one caveat: don't use SVG for photographs or complex gradients. File size explodes.
Inline your critical SVGs directly in the HTML to skip an extra request:
```html <svg width="24" height="24" viewBox="0 0 24 24"> <path d="..."/> </svg> ```
For decorative SVGs, reference them as `<img>` or CSS background.
10. Audit Your Existing Images
Here's the fastest way to find image problems on your site: run it through a real browser audit.
Our free SEO audit tool checks image file sizes, format usage, alt text coverage, CLS contributions, and whether your images have proper width/height attributes. You get a list of specific images that need fixing and what to do about each one.
You can also use Chrome DevTools. Open Network tab, filter by "Img", sort by Size. Anything over 500 KB is probably unoptimized. Anything over 1 MB definitely is.
The Compound Effect
No single image optimization is dramatic. Compressing one hero image saves 200 KB. Using srcset saves 400 KB on mobile. Lazy loading saves a second off time-to-interactive. But stack all ten of these and you're looking at:
- 60 to 80 percent smaller page weight - 2 to 4 second faster LCP on mobile - 5 to 15 point improvement in Lighthouse - Zero CLS from images - Better image search rankings from proper alt text - Lower bandwidth costs at scale
That's the kind of foundation work that makes everything else you do (SEO, conversion optimization, paid ads) more effective.
Want Us To Do It For You?
Image optimization is included in every engagement at Axion Deep Digital. If your site is slow because of unoptimized images (and most are), check out our website speed optimization service. We do full image pipeline audits, format conversion, srcset generation, and CDN setup as part of the work.
Or run a free SEO audit first and see exactly what's wrong. Takes 60 seconds. No signup, no email, just results.
Ready to build a website that performs?
Let us audit your current site, identify the biggest opportunities, and build a plan to grow your traffic and leads.