On a typical web page, images account for more transferred bytes than HTML, CSS, and JavaScript combined. They are also the part of SEO most sites get wrong — not from difficulty, but from neglect. This guide orders the fixes by impact, so you spend effort where it counts.
1. Size images to their display size (the 90% fix)
The most common and most expensive mistake: serving a 4000×3000 camera export inside a 400-pixel-wide card. The browser downloads megabytes, then throws 95% of the pixels away. No format choice or fancy technique recovers what right-sizing saves.
Practical rule: resize to at most 2× the largest displayed width (2× covers high-DPI screens). A 400px-wide card needs an 800px image, full stop. For layouts that vary, srcset lets the browser pick the right file per device:
<img src="photo-800.webp"
srcset="photo-400.webp 400w, photo-800.webp 800w, photo-1600.webp 1600w"
sizes="(max-width: 600px) 100vw, 400px"
alt="..." width="800" height="450">
2. Compress, then pick the right format
After sizing, compression: photos at JPEG/WebP quality ~80 are visually indistinguishable from quality 95 at roughly half the bytes. Our image compressor resizes and compresses in one step in your browser; the full format decision tree (WebP vs AVIF vs PNG) is in our image formats guide. Short version: WebP for nearly everything on the web, PNG only for graphics with sharp edges, AVIF where every kilobyte counts.
3. Always set width and height (layout stability)
An <img> without dimensions has zero height until the file arrives — then the page jumps as content shoves downward. That jump is Cumulative Layout Shift, one of Google's Core Web Vitals, and images without dimensions are its leading cause. Set width and height attributes (the browser reserves the space, CSS still controls final size) and the jump disappears. This is a one-attribute fix for a ranking-relevant metric.
4. Alt text: for readers first, rankings second
Alt text is read aloud by screen readers and displayed when images fail — it's an accessibility feature that search engines also use to understand images. Write it as a description for someone who can't see the image:
- Bad:
alt="image1"oralt="laptop code programming developer coding"(keyword stuffing reads as spam to both users and Google). - Good:
alt="Bar chart: WebP files average 30% smaller than JPEG at equal quality". - Decorative images (background flourishes):
alt=""— explicitly empty, so screen readers skip them.
File names help marginally too: laravel-queue-dashboard.webp beats IMG_4821.webp — name files like you'd want them found.
5. Lazy-load below the fold — and only below
Native lazy loading is one attribute: loading="lazy". Images far down the page don't download until the user scrolls toward them. The counterpart matters just as much: your hero image — the largest thing visible on load — must not be lazy; lazy-loading it delays Largest Contentful Paint, the Core Web Vital that measures perceived load speed. Above the fold: eager (optionally fetchpriority="high"). Below: lazy. Audit tip: if you added loading="lazy" globally via a template, check what it did to your hero.
6. Verify with the tools Google actually uses
Don't guess — measure. PageSpeed Insights names your specific offenders ("Properly size images", "Serve images in next-gen formats") with per-file byte savings, and reports your real-user Core Web Vitals. The DevTools Network tab, filtered to images with cache disabled, shows exactly what each page transfers — sort by size and the top three entries are usually your whole problem. Re-run after fixing; image work is unusually satisfying because the numbers move immediately.
The priority list, restated
- Resize to display size (biggest win, always).
- Compress at quality ~80 and use WebP.
- Set width/height on every image (kills CLS).
- Honest, descriptive alt text on content images.
loading="lazy"below the fold — never on the hero.
Do these five and you're ahead of the vast majority of the web — including, in our experience, most sites that consider themselves optimized.