The short version
- To optimize images for web, export each image at the size it is displayed, roughly doubled for high density screens, rather than uploading the original.
- AVIF and WebP produce much smaller files than JPEG and PNG at similar visual quality, and every current browser supports WebP.
- The srcset and sizes attributes let the browser download the smallest image that still looks sharp on each screen.
- Lazy load images below the fold with loading="lazy", but load the main hero image eagerly with fetchpriority="high", because it usually decides Largest Contentful Paint.
- Always set width and height on images so the browser reserves space and the layout does not jump while they load.
On this page
To optimize images for web without visible loss, do five things: export each image at the pixel size it is displayed (about twice that for sharp screens), choose a modern format such as AVIF or WebP, compress to a moderate quality and compare by eye, serve several sizes with srcset, and lazy load anything below the fold. Those steps clear most of the image warnings in Lighthouse and usually cut page weight dramatically, because the original photo straight from a camera or design tool is many times larger than the screen needs.
Step 1: export at the size you display
An image shown 800 pixels wide does not need to be 4,000 pixels wide. Lighthouse flags oversized images because the extra pixels are downloaded, decoded and thrown away. Measure how wide the image appears in your layout at its largest, then export at roughly twice that width for high density phones and laptops. Going beyond two times rarely looks sharper and always costs bytes.
Displayed at
Export width
Displayed at
Export width
Displayed at
Export width
Export width
Displayed at
Export width
Website hero 1920×1080
1920 × 1080
Blog banner 1200×600
1200 × 600
Link preview 1200×630
1200 × 630
Step 2: choose the right format
Format matters more than any compression slider. AVIF usually gives the smallest file, WebP comes close and is supported everywhere current, and JPEG and PNG remain the safe fallbacks. WebP vs PNG and PNG vs JPG go deeper on each pair.
Notes
Notes
Notes
Notes
Notes
linear-gradient(160deg, #0f172a 0%, #1e3a8a 50%, #0ea5e9 100%)Step 3: compress, then look
Lossy formats have a quality setting, and the right value depends on the image. Start around 75 to 80 for WebP and around 50 to 60 for AVIF, export, and compare against the original at 100% zoom. Lower it until you can see a difference, then step back up once. Faces, fine text and gradients need more quality than busy landscapes. Image compression explains what the encoder throws away.
Strip metadata such as camera details and embedded thumbnails while you are there. Most export tools do it with one checkbox, and it removes bytes nobody sees.
Step 4: responsive markup with srcset and sizes
With several widths exported, let the browser pick. srcset lists the files and their widths; sizes tells the browser how wide the image will appear. The browser then downloads the smallest file that is sharp enough for that screen.
<picture>
<source type="image/avif"
srcset="/img/hero-960.avif 960w, /img/hero-1440.avif 1440w, /img/hero-1920.avif 1920w"
sizes="100vw" />
<source type="image/webp"
srcset="/img/hero-960.webp 960w, /img/hero-1440.webp 1440w, /img/hero-1920.webp 1920w"
sizes="100vw" />
<img src="/img/hero-1920.jpg" alt="Morning light over the harbour"
width="1920" height="1080" fetchpriority="high" decoding="async" />
</picture>For an image inside a column, describe the layout in sizes, for example sizes="(min-width: 1024px) 720px, 100vw". Getting sizes wrong is the most common reason a responsive setup still downloads the big file.
Step 5: loading hints that matter
<!-- Below the fold: let the browser wait -->
<img src="/img/team-720.webp" alt="The team at the spring workshop"
width="720" height="480" loading="lazy" decoding="async" />
<!-- The hero: fetch first, never lazy -->
<img src="/img/hero-1920.webp" alt="Morning light over the harbour"
width="1920" height="1080" fetchpriority="high" />Common mistakes
loading="lazy"on the hero image- No width and height, so the page jumps
- One huge file for every screen
- A JPEG of a flat logo or screenshot
- Gradient backgrounds saved as images
Instead
- Hero loads eagerly with
fetchpriority="high" - Set both attributes on every img
srcsetwith three or four widths- SVG or PNG for flat graphics
- CSS gradients, with grain if needed
These hints map directly to Core Web Vitals. The hero image is often the Largest Contentful Paint element, which web.dev suggests should render within 2.5 seconds, and missing dimensions are a classic cause of layout shift. If your hero is a video rather than an image, the same thinking applies in video backgrounds for websites.
A checklist before you publish
- 1
Measure the slot
Find the largest displayed width of each image in your layout.
- 2
Export at the right sizes
One to two times the slot width, plus smaller versions for phones.
- 3
Pick the format
AVIF or WebP for photos and gradients, SVG for logos, PNG only when it wins.
- 4
Compress by eye
Lower quality until you see a change, then raise it a step.
- 5
Mark it up
srcset,sizes,width,height,alt, and lazy loading below the fold. - 6
Test it
Run Lighthouse in an incognito window and check the image audits and LCP element.
Much of this is easier when the image is made at its final size in the first place. In Gradiently you design once and Pro resizes to every size in one step, then exports PNG, JPG or SVG at exact dimensions up to 4K, so the hero, the banner and the Open Graph image each start at the size the page will show.
Questions people ask
How do I optimize images for web without losing quality?
Export at the displayed size, use AVIF or WebP, lower the quality setting only until you can see a difference, and serve several sizes with srcset. Most visual loss comes from heavy compression, not from resizing.
What is the best image format for websites?
WebP is the safe modern default and AVIF is usually smaller still. Use SVG for logos and icons, and keep JPEG or PNG as fallbacks.
Should I lazy load all images?
No. Lazy load images below the fold, but load the main hero image eagerly, because delaying it slows Largest Contentful Paint.
What size should website images be?
About twice the width they are displayed at, for sharp high density screens. A full width hero at 1920 px covers most displays.
Why does Lighthouse say my images are not properly sized?
The file has more pixels than the space it fills on the page. Export a smaller version and use srcset and sizes so the browser picks the right one.
Written by Gradiently
The team behind Gradiently, a design tool built around Marks: living gradients that make everything you design look like yours.
See our profile