webroad.online
  1. 1Web
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Tooling
  8. 8React
  9. 9State management
  10. 10Next.js
  11. 11Forms
  12. 12Data and backend
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Animations
  16. 16Testing
  17. 17Architecture
Web · Lesson 5 of 7

Image optimization

Format, size, compression, lazy vs priority, reserved space and next/image.

Updated

Why images matter

On most sites images make up over half of the page weight and are usually the LCP element (the largest visible element). A single 4 MB photo straight from a phone can make a page slow no matter how good the rest of the code is.

Image optimization comes down to 5 decisions: format, size, compression, when it loads and how you reserve space.

1. The right format

Format For Size vs JPEG
AVIF photos, complex images ~50% smaller
WebP photos, illustrations, transparency ~25–35% smaller
JPEG photos (universal fallback) baseline
PNG screenshots with text, exact transparency much larger for photos
SVG logos, icons, vector illustrations tiny, infinitely scalable
GIF — no — an MP4 / WebM video is 5–10× smaller

2. The right size

Don't serve a 3000px image in a 300px card. The rule: the image is the displayed width × the screen density (usually 2×). With srcset + sizes (see Images and media), the browser picks the right variant itself.

3. Compression

Quality 75–85 is usually visually indistinguishable from 100 at half the size. For SVG, run SVGO (removes metadata, simplifies paths).

4. When it loads

Image What to do
the main image, visible immediately (LCP) not lazy; fetchpriority="high" / priority in next/image
below the fold loading="lazy" — loads only when it gets close
decorative backgrounds CSS, possibly smaller / blurrier

5. Reserve the space

width + height (or aspect-ratio in CSS) → the browser reserves the space before the image arrives → no CLS.

next/image — all of it, automatically

import Image from 'next/image'
import hero from '@/shared/assets/hero.jpg'          // static import: dimensions + blur automatically

<Image src={hero} alt="The team at the office" priority placeholder="blur" sizes="100vw" />

<Image
  src={product.imageUrl}                               // remote image
  alt={product.name}
  width={600}
  height={600}
  sizes="(min-width: 64rem) 33vw, 100vw"
/>
What next/image does How
converts to AVIF / WebP based on what the browser accepts
generates several sizes automatic srcset; you only provide sizes
lazy by default priority for the LCP image
prevents CLS requires width/height, a static import or fill
placeholder placeholder="blur" (automatic with static imports)
caching optimized images are cached on the server / CDN
Prop When
sizes always when the image has no fixed width — without it the browser may download the largest variant
fill the image fills a parent with position: relative and dimensions (cards, heroes)
quality 75 by default; you rarely need more
images.remotePatterns in next.config.ts required for images from other domains (security)

Where images live

Source Recommendation
project images (logo, illustrations) in the repo, imported statically
user-uploaded images storage (S3, Vercel Blob, Cloudinary) + next/image with remotePatterns
many images, transformations (crop, filters) an image service / CDN (Cloudinary, imgix) with a custom loader

Checklist

  • modern format (AVIF / WebP), SVG for icons
  • the right size + sizes
  • the LCP image with priority, the rest lazy
  • width / height, or fill inside a sized parent
  • descriptive alt and a meaningful file name (also helps SEO)
  • no GIFs — a muted autoplay loop playsinline video instead

Summary

  • Images usually decide LCP and page weight.
  • AVIF/WebP, the right size, quality ~75–85, lazy below the fold, priority for LCP, reserved dimensions.
  • next/image does almost everything — you provide alt, sizes and priority.

Official sources

Exercises

Was this page helpful?

One tap — no account needed.