webtrajans
en

Image optimisation for the web: formats, sizes and compression

Images are usually the heaviest part of a web page. Choosing the right format, size and loading strategy can cut page weight by more than half with no visible loss.

Updated: 5 min read

A modern phone camera produces photos around 4000 × 3000 pixels. Uncompressed, that’s 12 million pixels and roughly 36 MB of raw colour data; even as a JPEG it’s often 3–5 MB. Shown in an 800-pixel-wide blog column, about 95% of those pixels are wasted, and every visitor on mobile data pays for them. Image optimisation is usually the single biggest, easiest speed win on a website.

Choosing the right format

Format Best for Transparency Animation Notes
JPEG Photos No No Universal fallback; lossy
PNG Screenshots, graphics needing lossless quality Yes No (APNG aside) Large for photos
WebP Photos and graphics Yes Yes Typically 25–35% smaller than JPEG at similar quality
AVIF Photos, especially large ones Yes Yes Often smaller than WebP; slower to encode
SVG Logos, icons, simple illustrations Yes Yes (CSS) Vector: sharp at any size, tiny files
GIF Legacy animation Limited Yes Replace with MP4/WebM video or animated WebP

Practical rule: SVG for logos and icons; AVIF or WebP for photos, with JPEG as a fallback if you need to support older devices; PNG only when you really need lossless pixels. Convert existing files with our WebP converter.

Getting dimensions right

Resize before you upload. Work out the largest size the image is displayed at in CSS pixels, then double it for high-density (retina) screens:

  • Blog content column 760 px wide → export at about 1520 px.
  • Product card thumbnail 300 px → about 600 px.
  • Full-width hero → 1600–2400 px depending on design, with smaller versions for mobile via srcset.

Going beyond 2× rarely brings visible benefit but always costs bytes. Our image resizer does this in the browser without uploading files anywhere.

Compression: how much is enough?

Lossy formats have a quality setting (usually 0–100). The visual difference between 100 and 80 is hard to see, but the file size difference is large.

  • JPEG: quality 75–85 is a good default for photos.
  • WebP: 75–80.
  • AVIF: lower numbers look better than in JPEG; around 50–65 is common, but compare visually.
  • PNG: use lossless optimisation, or quantisation (reducing the palette) for flat graphics.

Also strip unnecessary metadata (EXIF camera data, GPS location, colour profiles you don’t need): it saves bytes and avoids leaking where a photo was taken. Our image compressor runs locally in the browser and shows before/after sizes.

Example: a 4032 × 3024 JPEG of 4.2 MB, resized to 1600 px wide and saved as WebP at quality 78, typically ends up somewhere around 150–250 KB, depending on detail. That is a reduction of over 90%.

Responsive images with srcset

Let the browser pick the right file for the screen:

<img
  src="/img/kitchen-800.jpg"
  srcset="/img/kitchen-480.jpg 480w,
          /img/kitchen-800.jpg 800w,
          /img/kitchen-1600.jpg 1600w"
  sizes="(max-width: 700px) 100vw, 760px"
  width="1600" height="1067"
  alt="Oak kitchen with island and pendant lights">

And serve modern formats with a fallback using <picture>:

<picture>
  <source type="image/avif" srcset="/img/kitchen-1600.avif">
  <source type="image/webp" srcset="/img/kitchen-1600.webp">
  <img src="/img/kitchen-1600.jpg" width="1600" height="1067" alt="Oak kitchen">
</picture>

Always include width and height (or CSS aspect-ratio) so the browser reserves space and the layout doesn’t jump, which protects your CLS score.

Lazy loading done right

Native lazy loading is one attribute:

<img src="gallery-5.webp" loading="lazy" width="800" height="600" alt="...">
  • Do lazy-load images below the fold: galleries, long article images, footers.
  • Don’t lazy-load the hero or the first product image. It’s likely your Largest Contentful Paint element, and delaying it hurts. Use fetchpriority="high" on it instead.
  • Avoid JavaScript lazy-loading libraries when the native attribute is enough.

Automating it: CMS and CDN options

Doing all this by hand for every upload is tedious, so let your stack help:

  • WordPress creates several resized versions of each upload and outputs srcset automatically; it also adds loading="lazy" to most images (and skips the first ones it guesses are above the fold). Optimisation plugins can convert uploads to WebP or AVIF.
  • Shopify and most hosted platforms serve resized, modern-format images from their CDN when you use the theme’s image helpers.
  • Image CDNs (Cloudflare Images, Bunny Optimizer, imgix, Cloudinary) resize and convert on the fly based on URL parameters and the visitor’s browser.
  • Frameworks like Next.js and Astro include image components that generate sizes and formats at build time.

Even with automation, upload sensible originals: a 2,400-pixel JPEG rather than a 50-megapixel camera file, which wastes storage and processing time.

Alt text and file names

Alt text is for people using screen readers and for when images fail to load; it also helps search engines understand images. Describe what matters in context (“Oak kitchen with island and pendant lights”), not “image1” or a list of keywords. Decorative images get an empty alt="". Descriptive file names (oak-kitchen-island.webp) help a little for image search.

Common mistakes

  • Uploading straight from the camera or phone and relying on CSS to shrink it.
  • Using PNG for photographs: files several times larger than JPEG/WebP.
  • Lazy-loading everything, including the hero image.
  • Missing width/height, causing layout shifts.
  • Huge background images in CSS that the browser discovers late.
  • Re-compressing an already compressed JPEG repeatedly, adding artefacts each time. Keep originals and export once.

Checklist

  1. Logos and icons in SVG; photos in WebP/AVIF with JPEG fallback where needed.
  2. Images resized to display size × 2 at most.
  3. Compression around quality 75–85 (format-dependent), metadata stripped.
  4. srcset/sizes for images shown at different sizes across devices.
  5. width and height on every image.
  6. loading="lazy" below the fold; hero image eager with fetchpriority="high".
  7. Meaningful alt text. Then retest with our guide to speeding up your website.

Frequently asked questions

Which image format is best for websites?

For photos, AVIF or WebP give the smallest files at good quality, with JPEG as a fallback. For logos and icons, use SVG. Use PNG only when you need lossless quality or transparency and SVG isn't possible.

Do all browsers support WebP and AVIF?

WebP is supported by all current major browsers. AVIF is supported by current Chrome, Edge, Firefox and Safari; older devices may need a JPEG fallback via the picture element.

What size should images be for a website?

Match the largest size the image is displayed at, doubled for high-density screens. A full-width hero might need 1600–2400 px wide; a blog thumbnail shown at 400 px needs about 800 px.

Should I lazy-load all images?

No. Lazy-load images below the fold, but load the main above-the-fold image (often the LCP element) normally, ideally with fetchpriority=high.

Related guides