Home · Blog · Images

Resizing images for the web: display size, srcset and Core Web Vitals

The most expensive image mistake on the web is also the simplest: uploading a 4000-pixel photo into a 700-pixel slot. This guide covers how to work out the sizes you actually need, how srcset lets browsers pick, and why oversized images sabotage your LCP score.

A phone camera writes files around 4000 pixels wide. A typical article column displays images at 700. Serving the camera file into that column means every visitor downloads roughly thirty times the pixels they can see — bytes that cost time on mobile networks, memory on the device, and layout stability when the browser has to scale on the fly. Resizing is the cheapest performance optimisation there is, and unlike most, it is entirely under the publisher's control.

This article separates the three questions that are usually tangled together: how big the image displays, how big the file should be for screens of different densities, and how to hand the browser a set of sizes and let it choose.

Key takeaways

  • Ship pixels for the slot, not the camera: file width ≈ display width × device pixel ratio (1×, 2×, sometimes 3×).
  • Send several sizes with srcset and sizes and let each browser download only what its screen can use.
  • Declare width and height (or aspect-ratio) in markup so images stop pushing your layout around — that is a CLS fix, not a nicety.
  • The hero image is usually your LCP element; it deserves the most careful sizing of anything on the page.

Display size is a layout fact, not a file property

Start from the CSS, not the image. If your content column is 720 CSS pixels wide and the image spans it, the image displays at 720 — on every device. What differs is how many physical pixels sit behind those 720: a standard screen has one per CSS pixel (1×), most modern phones and laptops have two (2×), flagship phones three (3×). So the same slot wants a 720-pixel file for a 1× screen, 1440 for 2×, 2160 for 3×. Beyond 2×, returns diminish fast for photographs — few viewers can tell a 2× photo from a 3× one — which is why many sites cap supplied sizes at 2× for content images and reserve 3× for small, scrutinised elements like logos rendered as rasters.

Slot width (CSS px)1× file2× file3× file
360 (mobile card)360 px720 px1080 px
720 (article column)720 px1440 px2160 px
1180 (full-width hero)1180 px2360 px3540 px

srcset and sizes: offering a menu instead of a guess

Rather than picking one size for everyone, generate three to five widths of each important image and describe them in markup. The browser combines your list with the slot size and the device's pixel ratio and downloads the closest match — a phone on a slow connection gets the 720, a retina laptop gets the 1600.

<img src="harbour-800.jpg"
     srcset="harbour-480.jpg 480w,
             harbour-800.jpg 800w,
             harbour-1200.jpg 1200w,
             harbour-1600.jpg 1600w"
     sizes="(max-width: 760px) 100vw, 720px"
     width="1600" height="1000"
     alt="Fishing boats in the harbour at dawn">

The sizes attribute is the part everyone gets wrong: it tells the browser how wide the slot will be at different viewport widths, in the same terms as your CSS breakpoints. Get it wrong — say, leaving the default 100vw on a column that is really 720px — and browsers will systematically over-download. It is worth the five minutes to make sizes mirror your layout honestly.

What oversized images do to Core Web Vitals

Largest Contentful Paint (LCP) measures when the biggest element — very often the hero image — finishes rendering. An image file that is four times the necessary bytes can add seconds on a mid-range phone, and LCP past 2.5 seconds puts a page in Google's "needs improvement" band. Right-sizing is frequently the single largest LCP win available, ahead of minification, caching tweaks and most JavaScript diets.

Cumulative Layout Shift (CLS) is the other casualty: if the browser does not know an image's aspect ratio in advance, text jumps as each image loads. The cure costs nothing — include width and height attributes (or CSS aspect-ratio) and the browser reserves the exact space before a single byte arrives. Two attributes, zero shift. Finally, images below the fold should carry loading="lazy" so they do not compete with the hero for bandwidth, while the hero itself should never be lazy-loaded — that delays the very thing LCP is timing.

A sizing workflow you can repeat

  1. Measure the slot in your CSS at each breakpoint: full-width hero, column image, card thumbnail, avatar.
  2. Decide your density cap (2× for most content) and multiply: those products are your target widths.
  3. Generate each width from the master file, never by re-resizing a smaller copy upward or chaining down-sizes.
  4. Encode after resizing, at the quality your compression testing established — size first, then squeeze.
  5. Wire up srcset/sizes and dimensions, then check with a throttled connection that phones really do pull the small file.

Mistakes and pitfalls

Resizing in the browser with CSS only

Setting width: 100% on a 4000-pixel upload makes it look right and download wrong. CSS controls presentation, not payload — the full file still crosses the network.

Upscaling a small image to fill a big slot

Enlarging invents no detail; it produces a bigger, blurrier file. If the master is smaller than the slot, the honest fixes are a smaller slot, a different image, or accepting the softness at the size it exists.

One giant size "to be safe" for retina

Shipping 3× to everyone punishes the majority on 1× and 2× screens for a difference most cannot see in photographs. srcset exists so that safety does not have to be universal.

Common questions

How many srcset sizes are enough?

Three to five widths spanning your common slots is the practical range. More sizes give browsers finer choices but multiply storage and build time; fewer leave big gaps where a device must jump a size up.

Should thumbnails be cropped or scaled?

Scaled preserves the image; cropped to a fixed aspect ratio makes grids tidy but cuts content. Crop thumbnails from the master with a deliberate focal point, and keep the full frame for the main view.

Do I need to resize images that are inside PDFs or downloads?

Only if the PDF's own weight matters to you — the same pixel arithmetic applies inside documents, and an embedded 4000-pixel photo inflates a PDF just as surely as a page.

To wrap up

Image performance is mostly arithmetic: slot width, times density, offered as a small menu of sizes, with dimensions declared so the layout holds still. Do that arithmetic once per layout and your pages get faster for every visitor, on every visit, without a single line of JavaScript.

One last habit completes the workflow: after shipping responsive sizes, load the page with the browser's network panel throttled and a real phone form factor selected, and confirm the small variant is the file that actually arrives, at roughly the size your arithmetic predicted. When it is not, the cause is almost always a sizes attribute that flatters the layout or a template quietly emitting the full-size file as the src — both ten-minute fixes, but only once somebody has looked. Arithmetic plus one look is the whole discipline; the look is the part teams skip.

Try it yourself

The image resizer takes a master file, a target width and height, and produces the exact size you need — generated from your original each time, in your browser.

Open the Image Resizer