How to Optimize Pictures for Websites
Learn how to resize, compress, format, and deliver website images without blurry results, layout shifts, or unnecessary downloads.
Direct answer: Optimize website pictures by resizing them to the dimensions they are actually displayed, choosing a suitable format, tuning compression against visible quality, serving responsive variants, reserving layout space, and loading images according to their importance. Then measure the page on representative devices and networks. No single format or quality setting is best for every image.
1. Start with the delivered display size
An image should not routinely download far more pixels than its rendered slot needs. A 3,000-pixel desktop source delivered into a 360-pixel mobile card wastes bandwidth. Record the rendered width of each image at the breakpoints where it appears, then export a small set of candidates around those widths.
Classify each image
- Photographs: usually tolerate lossy compression and benefit from WebP or AVIF comparisons.
- Illustrations and screenshots: inspect text and sharp edges carefully because artifacts are easier to notice.
- Logos and icons: use SVG when the artwork is vector-based; minify and compress the SVG source.
- Transparent artwork: keep a format that preserves the required alpha channel.
- Animated images: verify that the selected format and browser support match the animation requirement.
Keep the original source asset. It lets you regenerate variants later when the layout, format support, or quality target changes.
2. Choose an image format by content and support needs
| Format choice | Good fit | What to verify |
|---|---|---|
| WebP | Photographs, illustrations, and images that need lossy or lossless compression | Compare actual bytes and visual quality; preserve a fallback when your support requirements need one |
| AVIF | Images where a smaller file may be possible at your target quality | Compare each asset and confirm browser support for your audience |
| JPEG | Photographs where established compatibility is useful | Check compression artifacts and avoid excessive quality reduction |
| PNG | Images needing lossless data or transparency | Check whether WebP or AVIF can meet the same visual and alpha-channel requirements |
| SVG | Logos, icons, and other vector artwork | Minify the text-based SVG and remove unnecessary metadata |
WebP and AVIF can compress better than JPEG or PNG for some assets, but neither is universally smaller at the same perceived quality. Export candidates, compare their byte sizes, and inspect them at the rendered size. The web.dev image performance guide describes the format and compression trade-offs.
3. Tune compression against visible quality
Lossy compression removes image information to reduce bytes. It often works well for detailed photographs, where small changes are hard to see. Lossless compression preserves image data but commonly produces larger files. Flat artwork, small text, line art, and high-contrast edges expose ringing, blockiness, halos, and blurred detail sooner.
- Export the same source at several quality settings.
- Measure the resulting files, including metadata and dimensions.
- View each candidate at its real CSS size and at a high-density display size.
- Check faces, text, edges, gradients, and transparent boundaries.
- Keep the smallest candidate that remains acceptable for that context.
Tools such as Squoosh and ImageOptim can help create and compare outputs. An automated image service can also generate variants, but you still need to define acceptable quality and verify representative pages.
4. Serve responsive sources with srcset and sizes
Responsive markup gives the browser enough information to choose an appropriately sized resource. The width descriptors in srcset describe the intrinsic widths of candidate files. The sizes value describes the image’s intended rendered width before the browser chooses a candidate.
<img
src='/images/article-800.webp'
srcset='/images/article-480.webp 480w,
/images/article-800.webp 800w,
/images/article-1200.webp 1200w,
/images/article-1600.webp 1600w'
sizes='(max-width: 640px) 100vw, (max-width: 1100px) 70vw, 800px'
width='800'
height='533'
alt='A mountain trail at sunset'
loading='lazy'
decoding='async'>
Make the sizes expression match your layout. If the image occupies half the viewport on desktop, saying 100vw causes the browser to consider unnecessarily large candidates.
Use <picture> for formats or art direction
<picture>
<source
type='image/avif'
srcset='/images/hero-800.avif 800w, /images/hero-1600.avif 1600w'
sizes='100vw'>
<source
type='image/webp'
srcset='/images/hero-800.webp 800w, /images/hero-1600.webp 1600w'
sizes='100vw'>
<img
src='/images/hero-1600.jpg'
width='1600'
height='900'
alt='A product dashboard on a laptop'
sizes='100vw'>
</picture>
Use separate crops when mobile and desktop need different composition. Do not create dozens of nearly identical variants without a clear layout need: each additional file increases storage, build, and cache-management work.
5. Reserve layout space and load at the right time
Declare accurate width and height attributes, or reserve the correct aspect ratio with CSS. This lets the browser allocate space before the bytes arrive and reduces layout movement.
.card-image {
aspect-ratio: 3 / 2;
width: 100%;
object-fit: cover;
}
Use loading='lazy' for images below the fold that do not need to be fetched immediately. Keep the hero or likely Largest Contentful Paint image eager. fetchpriority='high' can help a genuinely critical image, but applying it broadly can compete with other important resources.
<img
src='/images/hero-1600.webp'
width='1600'
height='900'
alt='A product dashboard on a laptop'
fetchpriority='high'>
<img
src='/images/related-800.webp'
width='800'
height='533'
alt='A team reviewing a chart'
loading='lazy'
decoding='async'>
These loading recommendations are covered in the responsive images guide and HTML images guide.
6. A complete optimization workflow
- Inventory: list image URLs, file sizes, intrinsic dimensions, rendered dimensions, format, and whether each image is above or below the fold.
- Prioritize: start with the largest downloads, oversized sources, and images that delay the page’s main content.
- Generate variants: create a small width set based on real layout slots and device densities.
- Compare formats: export WebP, AVIF, and a suitable fallback where required; compare bytes at acceptable visual quality.
- Wire responsive HTML: add
srcset, accuratesizes, and<picture>where format or crop selection needs it. - Set loading behavior: reserve space, lazy-load below-the-fold images, and keep the LCP candidate discoverable and timely.
- Measure again: inspect transferred bytes, request timing, layout movement, and the user-visible result on representative devices and network conditions.
- Regress-check: run the same checks after template, CSS, CDN, or image-pipeline changes.
7. Measurement checklist
- Does each image download close to the pixels its slot displays?
- Does the browser select the intended
srcsetcandidate at common viewport widths? - Are intrinsic dimensions or an aspect ratio declared?
- Is the hero image delayed by lazy loading or competing high-priority requests?
- Are below-the-fold images deferred?
- Do compressed outputs preserve readable text, sharp edges, and transparency?
- Have you checked both a fast connection and a constrained mobile connection?
- Did the change improve bytes without creating layout shifts or a slower LCP?
Image optimization can improve loading, including LCP, but image format changes alone do not guarantee passing Core Web Vitals. Google defines Core Web Vitals as real-world measures covering loading performance, interactivity, and visual stability; use the Core Web Vitals documentation when interpreting results.
8. Common mistakes and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Mobile downloads the desktop image | Missing or inaccurate srcset/sizes |
Generate smaller candidates and describe the actual rendered slot in sizes |
| Image looks blurry | Source is too small, quality is too low, or the browser selected the wrong candidate | Check intrinsic dimensions, candidate selection, and compression settings |
| Text in an image has halos or ringing | Lossy compression is too aggressive | Raise quality, use lossless output, or choose a format and source better suited to sharp graphics |
| Page jumps while images load | No dimensions or reserved aspect ratio | Add accurate width/height or CSS aspect-ratio |
| Hero image appears late | Hero was lazy-loaded or blocked by competing requests | Remove lazy loading, ensure it is discoverable in HTML, and consider fetchpriority='high' only for the critical image |
| Too many image files to maintain | More responsive variants than the layout needs | Reduce the width set to the breakpoints and display sizes you actually serve |
| AVIF is not displayed for some visitors | Browser support does not match the deployment assumption | Use <picture> with a supported fallback and verify target browsers |
| Optimization improved Lighthouse but users still report slowness | Other resources, scripting, server response, or interaction delays dominate | Measure the whole page and review Core Web Vitals in real conditions |
9. Performance, reliability, and cost considerations
Performance
Prioritize bytes that arrive before the main content and avoid oversized downloads. Responsive candidates reduce waste on small screens, while lazy loading saves bandwidth for content the visitor may never reach. Compression quality should be judged at the displayed size, not only by a file-size percentage.
Reliability
Keep a fallback for formats your audience may not support, retain source assets, and make image URLs deterministic so caches can reuse them. Test broken URLs, missing variants, transparent images, very wide images, and slow or interrupted connections.
Cost
Smaller files reduce transfer volume, but generating and storing many variants adds build and storage work. An image optimization service can automate transformation and delivery; compare its output, cache behavior, limits, and pricing with the operational cost of maintaining your own pipeline.
10. Or skip the browser setup
If you need screenshots of optimized pages for documentation, QA, or a content pipeline, ScreenshotNeo provides a website screenshot API. It removes cookie and consent banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and the response identifies the page verdict and billing status in headers. Its MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf.
See the ScreenshotNeo API documentation for parameters and options.
cURL
curl -G 'https://api.screenshotneo.com/v1/shot' \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-o shot.webp
Python
import requests
r = requests.get(
'https://api.screenshotneo.com/v1/shot',
params={'access_key': 'YOUR_API_KEY', 'url': 'https://stripe.com'},
timeout=90,
)
r.raise_for_status()
open('shot.webp', 'wb').write(r.content)
Node.js
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://stripe.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
ScreenshotNeo also supports full-page capture with lazy images loaded, element capture by CSS selector, custom CSS and JavaScript, device and viewport settings, retina scale, image resizing, caching with a chosen TTL, blocking selected resources, custom headers and cookies, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, and a usage API.
There are 1,000 screenshots per month on the free plan with no card. Paid plans start at $5 for 3,000 shots, and every feature is available on every plan. Create a free ScreenshotNeo account.
11. FAQ
Should every image be converted to AVIF?
No. Compare AVIF with WebP and an appropriate fallback for each image and quality target, then verify browser support.
How many responsive widths should I create?
Create enough candidates to avoid large gaps between the rendered slot and downloaded pixels at your real breakpoints and device densities. More variants increase maintenance.
Should I lazy-load the hero image?
Usually no. Keep the likely LCP image eager and reserve lazy loading for content below the fold.
Does image optimization guarantee better Core Web Vitals?
No. It can reduce image-related loading work, but Core Web Vitals also include interactivity and visual stability, and the whole page must be measured.
What is the safest way to prevent layout shifts?
Provide accurate intrinsic dimensions or reserve the image’s aspect ratio before the resource loads.


