Overview

Images can rank in Google Images, supply rich-result thumbnails, shift layout, and dominate page weight. Six attributes cover most of the work: filename, alt text, dimensions, format, loading behavior, and discoverability.

Name files like search queries

Google says filenames give light clues about an image’s subject. Use descriptive kebab-case (postgres-replication-architecture.png, not IMG_4827.png), based on the topic rather than the page slug since images get reused. Strip camera EXIF with exiftool, but keep IPTC creator and licensing fields if you want Google Images to show credit.

Write alt text for the screen reader, not the crawler

  • Describe what the image shows: “Diagram of Postgres logical replication with primary and replica” beats “Postgres image”.
  • Keep it to a short sentence and put long descriptions in the body or a caption. Do not repeat the caption verbatim.
  • Use alt="" for decorative images. Omitting the attribute counts as missing.
  • Keyword stuffing violates Google’s spam policy and fails screen-reader users.

Set width and height to prevent CLS

Set the intrinsic dimensions, not the rendered size, so the browser reserves the box before the image loads. A CSS aspect-ratio does the same job; use one or the other. A late image without reserved space is the most common CLS source; see core-web-vitals.

<img src="/images/postgres-replication.avif" width="1200" height="630"
     alt="Postgres logical replication architecture" loading="lazy" />

Ship AVIF and WebP with a fallback

Google Search supports BMP, GIF, JPEG, PNG, WebP, SVG, and AVIF, and recommends a fallback src inside <picture>. AVIF is often smaller than WebP at similar quality but slower to encode; savings vary by image.

<picture>
  <source srcset="/images/hero.avif" type="image/avif" />
  <source srcset="/images/hero.webp" type="image/webp" />
  <img src="/images/hero.jpg" width="1200" height="630" alt="Hero" />
</picture>

Compress to visually lossless; cwebp -q 80 is a starting point, so check by eye.

Lazy-load below the fold, prioritize the LCP image

  • Add loading="lazy" to images and iframes below the fold.
  • Give the LCP image fetchpriority="high" and a <link rel="preload"> in <head>; never lazy-load it.
  • Do not lazy-load images visible on first render.

Add images to the sitemap when JavaScript hides them

Image sitemaps surface images that JavaScript-rendered pages may hide from crawlers, including CDN-hosted ones. Google reads only <image:loc>, with up to 1,000 images per page URL. The format rules are in sitemaps-deep. Put captions in the page HTML.

Earn rich-result thumbnails with a large image and matching metadata

Google picks a page’s preferred image from the structured data image (or primaryImageOfPage) and og:image. Point both at the same high-resolution image that appears on the page; see og-images.

  • Google’s Article guidance recommends at least 50,000 pixels (width times height) and suggests 16x9, 4x3, and 1x1 versions in the image array. See structured-data.
  • Discover’s large previews need images at least 1200 pixels wide plus max-image-preview:large.

Cache images aggressively

Hashed filenames (hero-8f3a.avif) take Cache-Control: public, max-age=31536000, immutable. Unhashed ones need a shorter TTL plus stale-while-revalidate. Set headers at the CDN; see cloudflare-cache-rules.