August 10, 2026
Image Optimization for Core Web Vitals and SEO
Images are usually the heaviest asset a page loads and often the element that sets the Largest Contentful Paint metric. Resizing, compressing, and serving modern formats directly moves the Core Web Vitals numbers that now feed search rankings.

Core Web Vitals are the three speed-and-stability metrics Google folds into its page-experience ranking signal: LCP for loading, INP for interactivity, and CLS for visual stability. Of the assets a typical web page loads, images are almost always the single largest contributor to page weight and the most common element painted as the page's largest contentful paint. That makes image optimization one of the few interventions that visibly moves the LCP score, and the lab tools that report it, without rewriting the application.
The three metrics, and where images fit
The thresholds Google currently treats as "good" are:
Metric What it measures Good Poor
LCP Largest Contentful Paint <= 2.5s > 4.0s
INP Interaction to Next Paint <= 200ms > 500ms
CLS Cumulative Layout Shift <= 0.1 > 0.25
Images touch two of the three metrics directly. LCP measures the moment the largest visible element finishes rendering, and for most content pages that element is a hero image, a featured photograph, or a large product shot. The longer that image takes to download, decode, and paint, the higher LCP climbs. CLS measures unexpected layout movement, and images without reserved dimensions are the classic cause: the browser does not know how tall the image will be until it arrives, so the content below jumps downward when it finally renders.
INP measures input responsiveness and is less image-driven, but a main thread busy decoding a very large image can still delay event handlers, so the connection is not zero.
Resize to the display, not the original
The most common and most expensive mistake is serving an image at its native resolution. A photograph from a modern phone is easily 4000 pixels wide and several megabytes. If it is shown at 640 pixels wide in the layout, every byte beyond what 640 pixels needs is wasted bandwidth and wasted decode time, for every visitor, on every page load.
The fix is to export at the sizes you actually display, ideally at several sizes for responsive source sets. A reasonable pipeline produces a small variant for phones, a medium for tablets and small laptops, and a large for high-density desktop displays, then lets the browser pick. The resize-image tool does this without uploading anything to a server.
Two details catch people out. First, "2x" assets for high-density screens matter, but they should still be capped; a 2x version of a 640-pixel image is 1280 pixels, not 4000. Second, resize before compressing. Compressing an oversized image throws away quality on detail the visitor will never see, which is the worst of both options.
Compress, and prefer modern formats
Once an image is the right size, compression determines how many bytes that size costs. Modern formats beat legacy ones at equal perceived quality, often by a wide margin. WebP is typically 25 to 35 percent smaller than JPG or PNG for the same visual result, and AVIF goes further still for photographs, at the cost of slower encoding. Browser support for both is now broad enough that serving them as the primary format is a safe default.
A practical serving pattern is the picture element with a fallback:
<picture>
<source srcset="/hero.avif" type="image/avif" />
<source srcset="/hero.webp" type="image/webp" />
<img src="/hero.jpg" width="1280" height="720" alt="Hero image" loading="lazy" />
</picture>
The width and height attributes on the img are not decorative. They let the browser reserve the aspect-ratio box before the file arrives, which is exactly what prevents the layout shift that drives up CLS. Set them always, even when you are confident the image is above the fold.
For below-the-fold images, add loading="lazy" and decoding="async" so the browser defers them until they are near the viewport. For the LCP image itself, do the opposite: load it eagerly, give it high fetch priority, and consider preloading it so the request starts before the HTML parser reaches the img tag. The image converter handles the format round trip, and compress-image dials the quality down to the point where the size stops shrinking visibly.
Try it: Image Compressor
Shrink JPEG or WebP file size with a live quality preview, right in your browser.
Cache headers and CDN behavior
A byte cached is a byte not re-downloaded. Static image assets should ship with long cache lifetimes and a content-based filename, so that when the file changes the URL changes and the cache busts cleanly.
Cache-Control: public, max-age=31536000, immutable
A CDN in front of the origin shortens the network leg for every repeat visit and is the single most effective thing to add to an otherwise slow image pipeline, after the images themselves are small. Pair it with responsive source sets so a mobile visitor on a slow connection is served the small variant rather than a cached large one.
What moves the number, in order
If the lab report shows a poor LCP and the goal is to bring it under 2.5 seconds, the order of operations that usually pays off is: confirm the LCP element is actually an image (the lab tool will name it), resize it to the display width, recompress it as WebP or AVIF, reserve its dimensions in the markup, preload it, and then verify in a fresh run that the number moved. Most pages see LCP drop meaningfully after the first two steps alone, which is also the cheapest part of the work.