The most common image optimization mistake I see isn't a wrong format or a missing attribute. It's testing on your own machine and concluding everything is fine. Your browser has already cached the images. Your internet is fast. Your laptop is powerful. You are the worst possible test subject for your own website.
When you visit your own website, your browser caches everything. Images, fonts, scripts — all of it gets stored locally after the first load. Every subsequent visit, those files load from your disk, not from a server. Your experience of "this loads fast" is almost entirely from cache.
Your users aren't cached. They're hitting your site for the first time. Every file has to be fetched from scratch, over whatever connection they happen to be on, on whatever device they're using. That experience can be completely different from yours.
I learned this the embarrassing way. I spent a week convinced my site loaded in under a second. Then I ran PageSpeed Insights and got a 43. The hero image was 1.4MB. I'd never noticed because I'd cached it months ago.
Open DevTools → Network tab → check "Disable cache" → hard reload. That's your real first-load experience. While you're there, throttle the connection to "Fast 3G" — that's closer to what a mobile user on a patchy connection gets. If your images take more than two seconds to appear on Fast 3G, you have a problem.
I'm going to make some assumptions about you: you're probably on a laptop or desktop, probably on WiFi or a fast wired connection, probably in a city. If you're reading a web development article, the odds are good.
Your users are not necessarily you. A significant portion of web traffic comes from mobile devices on cellular connections, from lower-end Android phones, from regions where network infrastructure is worse. Even in high-income countries, mobile data speeds vary enormously — a subway commuter or someone in a rural area can be on a connection that's dramatically slower than your office WiFi.
This matters for images specifically because images are the largest files on most pages. A 1MB image that arrives in 200ms on your connection might take 4 seconds on theirs. Same file. Completely different experience.
I'm not trying to make a political point here — I'm making a practical one. If you optimize for the average of your actual users rather than for yourself, you will have a faster site. That's it.
There are a lot of image optimization techniques floating around: lazy loading, preloading, srcset, CDN delivery, HTTP/2, priority hints. They're all useful. But if I had to pick one thing that has the most direct impact on how fast an image appears for a first-time visitor, it's file size.
Smaller file = less to download = arrives sooner. The relationship is that direct. Everything else is about loading strategy — when and how the browser fetches images. File size is about how long that fetch takes once it starts.
In my experience, most sites that have slow image loading aren't doing anything clever wrong — they just have images that are larger than they need to be. Usually by a factor of 3–5×. That's not a configuration problem. That's a format and export problem, and it's fixed before the image ever goes on the server.
| Scenario | Typical file size | Download time on Fast 3G (~1.5 Mbps) |
|---|---|---|
| 1200px hero image, PNG from Figma | 1.2–2MB | 6–11 seconds |
| Same image, exported as JPG at 85% | 200–350KB | 1–2 seconds |
| Same image, converted to WebP at 82% | 120–200KB | 0.6–1 second |
| Same image, WebP + resized to actual display width | 60–100KB | 0.3–0.5 seconds |
That last row is where most sites could be, and most are sitting somewhere in the first or second row. The gap isn't a small optimization — it's the difference between a page that feels instant and one that feels broken.
The most common format mistake I see isn't using JPG when you should use WebP. It's using PNG when you should use JPG — and specifically, using PNG for photographs.
PNG is lossless, which sounds strictly better. For photographs on a website, it's almost always worse. Lossless compression isn't designed for the continuous-tone data in photos. A photograph as a PNG can easily be 5–8× larger than the same image as a compressed WebP with no perceptible quality difference at normal viewing sizes.
People use PNG for photographs because it feels "safe." You're not losing any quality, so how could it be wrong? It's wrong because the file is enormous, and your users are downloading 5× more data than they need to see the same thing.
Here's the decision I actually use:
The practical question for anything that isn't clearly a graphic or icon: does this image have a lot of gradients, texture, and continuous color variation? If yes, it's a photograph for format-selection purposes. Use WebP.
I built this site partly as a tool and partly as something I'd actually maintain and take seriously. So when I ran the first proper audit, I found the same things I just described.
The hero image was a PNG. It was 1.4MB. I'd exported it from a design tool and dropped it in without thinking. Converting it to WebP at 82% quality brought it to 180KB. LCP on mobile went from 5.2 seconds to 1.8 seconds. That one change moved me from "Poor" to "Good" on Core Web Vitals.
The second thing I found: I hadn't set explicit width and height on several images. This was causing layout shift — the page would render, then jump when images loaded. Fixing that dropped CLS from 0.18 to nearly zero. Both of these were afternoon fixes, not engineering projects.
The third thing, which I'm still working on: I didn't have srcset on most images. Mobile users were downloading the same 1200px image as desktop users and displaying it at 375px. That's about 10× more pixels than needed. Setting up proper responsive images requires exporting multiple sizes, which is more friction, but the bandwidth savings for mobile users are significant.
<!-- What I had --> <img src="hero.webp" alt="..."> <!-- What I should have had from the start --> <img src="hero-800.webp" srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1600.webp 1600w" sizes="(max-width: 600px) 100vw, 800px" alt="..." width="800" height="420" fetchpriority="high" >
Most image checklists are too long to be useful. Here's the short version — the things that have the most impact in the least time:
DevTools → Network → Disable cache → throttle to Fast 3G. Do this before anything else. You need to see what users see, not what you see.
Any PNG or JPG that's a photo should be WebP. Use the converter here — your files stay local, nothing is uploaded. Do this for every image above the fold first.
This prevents layout shift. Five minutes to audit and fix. No excuses for missing this one.
One attribute. Do not add it to your LCP image — that one should load immediately.
Don't guess. Let the tool tell you what's actually slow. Then fix that specific thing.
Run PageSpeed Insights on your URL. If it flags "Serve images in next-gen formats," "Efficiently encode images," or "Properly size images," images are the problem. It'll tell you exactly which ones.
At equivalent visual quality, yes. At equivalent file size, WebP looks better. The quality setting I use is 82% — at that level I've never been able to tell the difference on a screen at normal viewing distance.
A 90 score doesn't mean images are optimal — it means you're above a threshold. Check the individual LCP time. If it's above 2.5 seconds, there's still room to improve regardless of the score.
It depends on whether those pages get traffic. Pages that rank and get clicks are worth fixing. Archived posts from years ago that nobody reads — probably not worth the time.
If you've tested properly and images still aren't the issue — good. You've ruled out the most common problem. The blog has more on format selection and compression if you want to go deeper. And if you find something that doesn't convert correctly with the tools here, the contact page comes directly to me.