Optimising images for the web is not a single step — it's a workflow. Done well, it results in pages that load in under two seconds, score green on Core Web Vitals, and look sharp on every device from a 4K monitor to a mid-range Android phone on a 4G connection.

This guide walks through every step of that workflow, from picking the right format to implementing responsive images in HTML. By the end, you'll have a clear, repeatable process you can apply to every project.

Step 1: Start with the Right Dimensions

The single most wasteful thing you can do is serve a 4000×3000 pixel photo when it will only ever be displayed at 800×600. The browser scales it down, but it still downloads every byte of the full-resolution file.

Always resize images to the largest size they will actually be displayed at, plus a 2× multiplier for high-DPI (Retina) screens. For example:

Never, ever serve a raw 12 MP photo from a camera. Resize it first, then compress.

Step 2: Choose the Right Format

Format choice has a massive impact on file size. A quick guide:

Remember: using JPEG for a logo or screenshot introduces ugly compression artefacts around edges and text. Using PNG for a photograph unnecessarily balloons file size. Match the format to the content type.

Step 3: Compress the File

Even after resizing and choosing the right format, most images can be compressed further with no perceptible quality loss. This is where a tool like TinyFication comes in.

As a general guide for compression levels:

Image type Recommended mode Expected reduction
Hero / banner image Quality 50–65%
Blog inline images Balanced 60–75%
Product thumbnails Aggressive 70–82%
Preview / placeholder images Maximum 78–88%

The goal is to reach a sweet spot where the file is as small as possible without the compression being noticeable to a normal viewer at typical viewing sizes. You can always zoom in and find artefacts — but at standard display sizes on a website, they're rarely visible above the Balanced compression level.

Step 4: Use Descriptive File Names and Alt Text

File names and alt text don't affect file size, but they matter enormously for SEO and accessibility. Both are part of "optimising images for the web" in the broader sense.

Step 5: Set Explicit Width and Height Attributes

This simple step prevents Cumulative Layout Shift (CLS) — one of Google's Core Web Vitals. When a browser encounters an <img> tag without explicit dimensions, it doesn't know how much space to reserve until the image downloads. Everything shifts as images pop in, creating a jarring user experience.

Always specify width and height on your image tags:

<img src="hero.jpg" alt="TinyFication hero image" width="1520" height="760">

These are the intrinsic dimensions of the image file, not the displayed CSS size. The browser uses them to calculate the aspect ratio and reserve space before the image loads.

Step 6: Implement Lazy Loading

Lazy loading tells the browser not to download images that are below the fold until the user scrolls near them. This dramatically reduces initial page load time, because you're only fetching the images the user actually sees first.

It requires one attribute:

<img src="blog-photo.jpg" alt="..." loading="lazy" width="800" height="400">

Important: do not add loading="lazy" to above-the-fold images (your hero, your logo). Lazy loading those will delay their appearance, harming your LCP score. Apply it only to images below the visible viewport on initial load.

Step 7: Use Responsive Images with srcset

Different screen sizes need different image resolutions. A 2880px image delivered to a 375px mobile screen wastes enormous bandwidth. The srcset attribute solves this by letting the browser choose the most appropriate image from a set you provide:

<img
  src="hero-800.jpg"
  srcset="hero-800.jpg 800w, hero-1200.jpg 1200w, hero-1600.jpg 1600w"
  sizes="(max-width: 600px) 100vw, 760px"
  alt="Hero image"
  width="1600" height="800"
>

The sizes attribute tells the browser how wide the image will be displayed at different viewport widths. Based on this, the browser fetches only the resolution it actually needs, saving bandwidth on mobile without sacrificing quality on desktop.

Step 8: Serve Images via a CDN

Even perfectly optimised images load slowly if they're served from a single origin server geographically distant from your visitors. A Content Delivery Network (CDN) caches your assets at edge locations worldwide, so images are served from a server close to each visitor.

Cloudflare Pages (which TinyFication uses), Vercel, Netlify, and similar platforms include a CDN automatically. If you're on traditional hosting, services like Cloudflare's free plan, BunnyCDN, or CloudFront are worth configuring.

Step 9: Set Proper Cache Headers

Images rarely change. Tell browsers to cache them aggressively so returning visitors don't re-download them on every page load. A Cache-Control header like the following instructs both browsers and CDN edges to cache the image for a full year:

Cache-Control: public, max-age=31536000, immutable

The immutable directive tells the browser not to re-validate the file even when the user force-refreshes the page — further reducing unnecessary requests. If you ever update an image, use a new filename (or append a query string) to bust the cache.

Putting It All Together: A Quick Checklist

Follow these steps consistently and your images will be smaller, faster, more accessible, and better for SEO — without sacrificing any visible quality.

Start with step 3 right now — it's free, instant, and requires no signup.

Compress images with TinyFication →