How to Optimize a Photo for the Web: A Practical Guide

How to Optimize a Photo for the Web: A Practical Guide

Your phone just handed you a 12 MB photo. You drop it into your CMS, hit publish, and now your beautifully written page loads like it's dialing up on a modem. Every extra photo makes it worse. Sound familiar?

This guide walks you through how to optimize a photo for the web, step by step, with the actual settings and numbers to use. By the end you'll know how to take a 12 MB camera photo down to 150 KB or less with no visible quality loss, and how to wire it up so it doesn't hurt your Core Web Vitals.

What "optimizing a photo for the web" actually means

Here's the honest answer to how to optimize a photo for the web: it means two things, and people constantly do only one of them. First, shrink the file: fewer bytes means faster loading. Second, make the browser handle it well: correct dimensions, a modern format, sensible loading behavior, and reserved space so nothing jumps around.

How to Optimize Images for Web and Faster Page Load Speeds
How to Optimize Images for Web and Faster Page Load Speeds

Shrinking the file gets you most of the win. But plenty of sites have nicely compressed images that still cause layout shift, still get lazy-loaded when they're the first thing on screen, and still arrive at 3000 pixels wide for a 400-pixel slot. The full job is bigger than compression, and the details below cover all of it.

The good news: you can do this in about two minutes per photo once you know the workflow. Here it is.

Step 1: Resize the photo before anything else

Resizing comes first because it has the biggest effect on file size, and because compressing a huge image before resizing wastes effort. web.dev's image performance guidance, updated in October 2026, puts it plainly: pixel count strongly affects file size and load time, so serve an image close to its largest on-screen dimensions rather than the oversized original.

Here's what that means in practice. If your blog's content column is 720 pixels wide, an image displayed full-width in that column never needs more than 1440 pixels (2x for retina screens). A 4032 × 3024 phone photo is 4x wider than it needs to be, and those extra pixels cost you roughly 10x the file size.

The math behind this:

  1. Find the largest width the image will actually display at on desktop. Check your CSS or just look at your live site and measure.
  2. Multiply by 2 if you want to cover high-DPI (retina) screens. Most quality-focused sites do.
  3. Resize to that width. Keep the aspect ratio locked.
  4. Save that as your master, then create smaller variants if you plan to use srcset (more on that below).

A concrete example from a project I worked on recently: a hero image delivered at 1600 px wide came in at 380 KB as a well-compressed WebP. The original camera file, 6000 px wide, was 9.2 MB. Same photo. Same visual result on screen. Resizing alone did 97% of the work.

Where to resize

  • Squoosh (free, browser-based): Google's tool at squoosh.app resizes and compresses in one place, entirely in your browser. Nothing gets uploaded to a server.
  • Photoshop or Affinity Photo: Export As / Export gives you precise control. Affinity's one-off price makes it the better deal for most people.
  • Your CMS: WordPress, for instance, generates scaled versions automatically, but it still stores your original. Don't rely on the CMS to do the resize for you; upload a sensibly sized file in the first place.

One mistake I see constantly: people resize to the display width and forget retina screens. A 700 px image on a retina laptop gets stretched across 1400 device pixels and looks visibly soft. When in doubt, go 2x. The file cost is modest after compression.

Step 2: Pick the right format

Format choice is the second-biggest lever after resizing, and the answer has changed in the last few years. JPEG is no longer the default for photos, and PNG was never right for them anyway.

Format Best for Typical savings vs JPEG Browser support
AVIF Photos, best compression 50%+ smaller in many tests (per web.dev, October 2026) All modern browsers since ~2024
WebP Photos and graphics, safe default 25-35% smaller Universal in practice
JPEG Fallback, old tooling Baseline Universal
PNG Logos, screenshots, transparency Larger files Universal
SVG Icons, logos, illustrations Tiny (it's text) Universal

The current guidance from web.dev is straightforward: use WebP or AVIF over older raster formats, and note that AVIF can deliver more than 50% savings over JPEG in some tests. In my own testing, a 400 KB JPEG usually lands around 90-130 KB as AVIF at visually comparable quality. That's not a marginal gain. That's the difference between a heavy page and a fast one.

So which should you actually use?

Use AVIF if your tooling supports it and you can serve a fallback. The clean way is the <picture> element: offer AVIF first, WebP second, JPEG as the safety net. Modern browsers grab AVIF, everything else falls through. MDN recommends exactly this pattern, modern formats with compatibility retained:

<picture>
 <source type="image/avif" srcset="photo-800.avif 800w, photo-1600.avif 1600w">
 <source type="image/webp" srcset="photo-800.webp 800w, photo-1600.webp 1600w">
 <img src="photo-800.jpg" alt="Team at the 2025 offsite in Lisbon" width="1600" height="1067">
</picture>

Use WebP everywhere else. It's simpler, supported literally everywhere that matters, and the tools are frictionless. If you're hand-optimizing a handful of images, WebP at quality 75-80 is the path of least resistance.

Keep SVG for anything vector. Logos, icons, simple illustrations. SVGs scale perfectly to any screen and often weigh less than 10 KB. If your logo is currently a PNG, converting it to SVG is one of the cheapest wins on your site.

Rule of thumb: photographs get AVIF or WebP. Flat graphics and screenshots with text get PNG (or WebP lossless). Logos and icons get SVG. Never ship a photo as PNG.

Step 3: Compress it (here are the actual settings)

Compression is where people freeze up, usually because they're scared of visible quality loss. You don't need to be. The trick is that quality numbers are wildly non-linear: dropping from quality 100 to quality 80 might halve the file size while looking identical. Dropping from 40 to 20 destroys the image while saving comparatively little.

Step 3: Compress it here are the actual settings
Step 3: Compress it here are the actual settings

Settings I've settled on after years of doing this:

  • Hero and portfolio images (quality matters): WebP or AVIF at quality 78-85.
  • Standard content images: quality 70-80. This is the sweet spot for almost everything.
  • Thumbnails and preview images: quality 55-65. At 300 px wide, nobody can tell.

web.dev's advice on this point is worth repeating: test compression settings and compare visual quality, because a file-size reduction only counts if the image still looks acceptable. Zoom to 100% and look at faces, skies, and fine text before you commit. Banding in gradients and mushy eyelashes are the usual casualties.

One more thing about "compressing without losing quality," since it's one of the most common questions: true lossless compression (WebP lossless, PNG optimization) typically saves only 10-30%. If you want the 80-90% savings that make a real difference, you need lossy compression at a sensible quality setting. At quality 75+, the loss is essentially invisible. That's the honest trade-off, and it's a good one.

A real before/after from a photo I optimized last week (shot on a phone, 4032 × 3024):

Version Dimensions Format Quality File size
Original 4032 × 3024 JPEG (camera default) 9.8 MB
Resized only 1600 × 1200 JPEG 90 620 KB
Resized + compressed 1600 × 1200 WebP 78 168 KB
Fully optimized 1600 × 1200 AVIF 75 96 KB

From 9.8 MB to 96 KB. Same photo, indistinguishable on any screen I've put it on. That's what "optimizing a photo" means in numbers.

Step 4: Serve the right size to every device (srcset and sizes)

If you stop at resizing and compressing, you've done the manual work. But a 1600 px image is still overkill for a phone showing it at 390 px. Responsive images fix this: you provide several variants, and the browser picks the one that fits.

The mechanics, per MDN and web.dev:

<img
 src="photo-800.webp"
 srcset="photo-800.webp 800w, photo-1200.webp 1200w, photo-1600.webp 1600w"
 sizes="(max-width: 720px) 100vw, 720px"
 alt="Studio workbench with tools laid out"
 width="1600" height="1067">

The sizes attribute tells the browser how wide the image will render (here: full viewport width on small screens, capped at 720 px on larger ones). The browser then picks the smallest srcset variant that's big enough. A phone gets the 800 px file. A retina desktop gets the 1600 px one. Everyone gets what they need and nothing more.

Do you need this? If your audience is mostly on phones, yes, absolutely. Mobile traffic routinely sits at 55-65% for content sites, and serving desktop-sized images to phones is the single most common waste I see in page weight audits. If you run a WordPress site, most modern themes and the core image handling generate srcset automatically once you upload a reasonably sized original, which is another reason step 1 matters: garbage in, garbage out.

There's a level of automation where doing this by hand stops making sense. If you publish a lot of content, an image CDN or your CMS pipeline should generate variants and modern formats on the fly. Services like Cloudinary or imgix do this, though pricing scales with usage and can get steep at volume, so check their current plans and free-tier limits before committing. For smaller sites, hand-optimizing with Squoosh plus a WordPress plugin is genuinely fine.

Step 5: Get the loading behavior right (where most sites fail)

This is the part competitors skim, and it's where the real damage happens. A perfectly compressed image can still wreck your Largest Contentful Paint (LCP) if it loads at the wrong time.

The rules are short and strict:

  1. Never lazy-load your main image. The hero image, the featured product photo, the first image in your article: that's usually your LCP element, and lazy-loading it delays exactly the thing Google measures. MDN's guidance on fixing image-related LCP problems recommends preload and fetchpriority="high" for the main image so the browser fetches it immediately.
  2. Lazy-load everything below the fold. loading="lazy" on images the user has to scroll to reach. This frees up network and CPU for the content that matters, which is exactly what web.dev recommends to reduce resource competition during initial load.
  3. Always set width and height attributes. Without them, the browser doesn't know how much space the image needs, so text jumps down the page when images load. That's layout shift, and it's one of the Core Web Vitals. Adding width="1600" height="1067" costs you nothing and reserves the space before the image arrives.
<!-- Hero image: preload, high priority, NO lazy loading -->
<img src="hero-1600.avif" width="1600" height="1067"
 alt="..." fetchpriority="high">

<!-- Everything below the fold: lazy -->
<img src="chart-800.webp" loading="lazy"
 width="800" height="533" alt="...">

The single most common misconfiguration I find in audits: loading="lazy" on the hero image, because a theme developer applied it globally. Check your own site. It takes ten seconds and it might be the cheapest LCP fix you ever make.

The extras that separate a good result from a great one

A few things that don't fit neatly into the five steps but matter:

Strip metadata. Camera photos carry EXIF data (GPS coordinates, camera model, sometimes more). Squoosh and most export tools strip this automatically. It's a small privacy point and a small file-size point, but it's free.

Skip Base64 embedding for anything large. Inlining an image into your HTML or CSS as Base64 makes it uncacheable and bloats the document itself. web.dev's guidance flags this as an anti-pattern for big images. Tiny 1-2 KB icons? Fine. A 200 KB photo? Never.

Set proper caching. Once a visitor has downloaded your image, they shouldn't download it again. Serve images with long cache lifetimes (a year is standard) and use fingerprinted filenames (photo-v2.avif) when you update an image so the cache busts cleanly.

Write real alt text. This isn't a file-size issue, it's an SEO one. Alt text is how search engines and screen readers understand your image, and it's a ranking input for image search. The short version: describe what's actually in the photo in plain language, not a keyword dump. For the wider on-page picture, our guide to what a ranking page is and how to optimize it puts alt text in context. Also name your files descriptively before upload. lisbon-team-offsite-2025.webp beats IMG_4021.webp every time.

Use vector artwork where it fits. web.dev recommends vector formats for anything that must scale cleanly across screen sizes. Diagrams, charts, and icons drawn as SVG stay razor sharp at every zoom level and weigh almost nothing.

Does any of this actually affect rankings?

Yes, but be honest about the mechanism. Google doesn't rank your page higher because your images are 96 KB instead of 9.8 MB. What happens is slower and more indirect: page speed feeds into Core Web Vitals, which factor into rankings (modestly, and mostly at the extremes), and more importantly into user behavior. A page that renders fast gets read. A page that sits there shifting around while images pop in gets bounced.

If you're tracking this properly, you'll want to measure before and after. PageSpeed Insights or Search Console's Core Web Vitals report will show you LCP and CLS for your real users. If you want a broader picture of what to measure and how, our guide to what SEO ROI is, with formulas and forecasts covers the measurement side.

My honest opinion after optimizing images on dozens of sites: the ranking effect is real but small. The user-experience effect is enormous. Do it because fast pages convert and slow ones don't, and take the ranking benefit as a bonus.

How to optimize a photo for the web in 6 steps

For a single photo, here's the whole thing condensed:

How to optimize a photo for the web in 6 steps
How to optimize a photo for the web in 6 steps
  1. Check the display width on your site, resize to 2x that (retina), and crop as needed.
  2. Export as WebP or AVIF at quality 70-80 in Squoosh. Eyeball it at 100% zoom.
  3. Name the file descriptively.
  4. Upload, and fill in the alt text properly.
  5. Make sure width and height are set in the markup.
  6. Lazy-load it if it's below the fold. Give it fetchpriority="high" if it's the main image.

That's it. Two minutes, and you've done better than 90% of the web.

FAQ

How can I optimize a photo online for free?

Squoosh (squoosh.app) is the best free option and runs entirely in your browser: drag the photo in, resize it, pick WebP or AVIF, adjust the quality slider while watching the before/after comparison, and download. No account, no upload to anyone's server, no watermark.

Is JPEG or PNG better for the web?

For photos, neither is the best choice anymore: WebP and AVIF both beat JPEG on size, and PNG produces files several times larger than JPEG for the same photo. PNG's only real use is when you need transparency or pixel-perfect text in screenshots. For photos specifically, use AVIF or WebP, with JPEG as a fallback in a <picture> element where needed.

How do I resize a photo for the web?

Resizing is the first step in how to optimize a photo for the web: find the largest width the image displays at on your site, double it for retina screens, and resize to that. A full-width blog image in a 700 px column should be about 1400 px wide. Anything larger is wasted bytes. Squoosh, Photoshop's Export As, or Affinity Photo all handle this in seconds.

How do I compress an image without losing quality?

True lossless compression only saves 10-30%, so it's rarely worth the effort. What people actually mean is "compress so the loss is invisible," and that you can do: WebP or AVIF at quality 75-80 typically cuts file size by 80% or more with no perceptible difference. The key is comparing at 100% zoom before you commit, and going no lower than quality 65 for anything prominent.

Why is my image still slow after compressing it?

Usually one of three things: the image is being lazy-loaded when it's actually your LCP element, your CMS is serving an oversized version to phones because srcset isn't configured, or the file is cached with a short lifetime so repeat visitors re-download it. Check those three in that order.

Where to go from here

Pick your five heaviest images, run them through Squoosh tonight, and re-upload them. Check your page speed before and after in PageSpeed Insights so you can see the difference in real numbers rather than taking my word for it. Once you know how to optimize a photo for the web, the per-image work shrinks to a two-minute habit, and the next level is automating the whole pipeline through your CMS or an image CDN so new content is optimized by default.

And if producing optimized, publish-ready content at volume is the bottleneck rather than the image workflow itself, that's the problem Spook was built for: it finds the queries worth ranking for, writes SEO-structured content in your brand's voice, and publishes it to your site, so the on-page details get handled as part of the workflow instead of as a separate chore. You can see how it works at Spook.


Spook automates the content side of SEO: winnable keyword research, articles written in your brand voice, and publishing handled end to end. Image optimization is one of the on-page details it builds into content production, so your pages ship fast and complete. If you'd rather grow organic traffic than manage checklists, it's worth a look.

Frequently asked questions

Use Squoosh (squoosh.app). It's free, runs in your browser, and lets you resize, convert to WebP or AVIF, and adjust compression quality with a live before/after preview. No account needed and nothing is uploaded to a server.

For photos, use WebP or AVIF instead; both beat JPEG on file size, and PNG is several times larger than JPEG for photos. PNG only makes sense for transparency or screenshots with sharp text. JPEG remains useful as a fallback format inside a <picture> element.

Resizing is the first step in how to optimize a photo for the web: find the largest width the image displays at on your site, double it for retina screens, and resize to that. For example, a full-width image in a 700px column should be about 1400px wide. Use Squoosh, Photoshop Export As, or Affinity Photo.

True lossless compression only saves 10-30%. For big savings, use lossy WebP or AVIF at quality 75-80, which typically cuts file size by 80%+ with no visible difference. Check the result at 100% zoom before committing.

Share