What downscaling has to decide
Going from 4000 pixels wide to 800 means the output has one pixel for every twenty-five in the source. Something has to decide what each output pixel should be.
The naive approach picks one source pixel per output pixel and discards the other twenty-four. That is fast, and on smooth content it is fine, because the discarded pixels were nearly identical to the one kept.
On fine repeating detail it is a disaster. Brick, roof tiles, fabric weave, hair, and small text all contain patterns finer than the sampling grid. Picking one pixel per cell samples that pattern at the wrong rate and produces aliasing — moiré, shimmer, and edges that jitter between frames if the image is ever animated or scrolled.
Averaging instead of picking
The correct answer is to average all twenty-five source pixels into the output pixel, so every input contributes and no detail is sampled at the wrong rate. That is what a proper box or area filter does, and it eliminates aliasing.
Doing it in one enormous step is expensive and, in most browser and application code, is not what happens. Many implementations use bilinear interpolation, which consults only the four nearest source pixels regardless of how far you are scaling down. At a 5x reduction, that means 4 pixels are consulted and 21 are ignored.
This is why the same photo resized in two different tools can look noticeably different. The difference is not quality settings; it is which pixels the resampler bothered to look at.
Stepped halving
The practical fix is to reduce in repeated halving steps rather than one jump. Take 4000 to 2000, then 2000 to 1000, then 1000 to 800.
At each halving, a four-nearest-pixel filter is consulting exactly the pixels that matter, because the scale factor is small. Every source pixel contributes to the stage below it, so detail is folded downward rather than dropped. By the time you reach 800, every one of the original pixels has influenced the result.
The cost is a few extra intermediate operations, which is negligible. The benefit is visible immediately on patterned content: brickwork stays as brickwork rather than turning into a shimmering interference pattern, and small text stays legible rather than breaking up.
Compress last
Compressing before resizing wastes the compression entirely. The encoder spends bits describing detail across four million pixels, and then you discard 95 percent of those pixels. The bits are gone and the quality loss stays.
Worse, the compression artefacts themselves get resampled. JPEG blocking is an 8x8 grid pattern, and downscaling it produces a fine texture that the second compression pass then has to encode as though it were real detail.
Resize the original, then compress once at your target quality. One generation of loss instead of two, and a smaller file at the end of it.
Upscaling is a different problem entirely
Downscaling has too much information and must discard some intelligently. Upscaling has too little and must invent it. Those are not symmetric problems and no resampling filter solves the second one.
Interpolation guesses each new pixel from its neighbours, which produces a larger, softer image. Any compression artefacts in the source are enlarged along with everything else, so a small heavily-compressed image enlarges into a big obviously-compressed one.
Roughly doubling is acceptable for viewing at a distance. Beyond that, the softness is unmistakable. Denoising and sharpening alongside the enlargement reads better than plain interpolation, which is what an image enhancer does, but none of it recovers detail that was never captured.
Working out the size you actually need
The right target is the largest size the image will really be displayed at, doubled if you are supporting high-density screens. A photo in a 600-pixel content column needs 1200 pixels, not 4000.
For full-width hero images, the practical ceiling is around 2000 pixels wide — above that, the extra bytes buy nothing that any common display can resolve. For thumbnails in a grid, measure the rendered cell rather than guessing; grids are usually far smaller than people assume.
Getting this right is worth more than every other optimisation combined. Serving a 4000-pixel photo into a 600-pixel slot wastes roughly 97 percent of the downloaded pixels, and no amount of clever format choice recovers that.
Downscaling text and screenshots
Text is the hardest content to downscale, because letterforms are exactly the fine high-contrast detail that resampling damages first. Below about 60 percent of original size, small interface text becomes unreliable no matter how good the filter is.
If a screenshot has to be readable, crop rather than scale. A tight crop of the relevant region at full resolution communicates far better than the whole screen shrunk to fit, and it is usually a smaller file too.
If it has to be scaled, use stepped halving and add a light sharpening pass afterwards, then check the result at the actual display size rather than zoomed in. A screenshot that looks acceptable at 100 percent zoom may be illegible in the context where it will be seen.
Frequently asked questions
Why does my resized photo look shimmery?
Aliasing. The resampler sampled fine repeating detail at the wrong rate instead of averaging it. Stepped halving avoids this.
Should I sharpen before or after resizing?
After. Sharpening first creates edge halos that the downscale then averages in permanently.
Should I compress before or after resizing?
After. Compressing first spends bits on pixels you are about to discard, and its artefacts get resampled into the result.
What is the best size to resize a photo for the web?
Match the largest size it will actually be displayed at, then double it if you are supporting high-density screens. Anything beyond that is wasted bytes.
Can I enlarge a small image without it going soft?
Not really. Interpolation guesses new pixels rather than recovering them. Doubling is usually the practical limit before softness is obvious.
Does the file format matter when downscaling?
For the resize itself, no. But keep a lossless source if you will resize repeatedly, since each JPEG round trip adds loss on top of the resampling.