Image Optimization for the Web: The Decisions That Matter
Learn which image formats, sizes and loading settings to use, and how to choose between CMS, build-time and image CDN pipelines for faster pages.
Image optimization for the web means delivering every image in a modern format, at the size it is actually displayed, with the loading behavior that suits its position on the page. That sounds like a checklist, and in part it is, but behind the checklist sit a handful of real decisions: which formats to produce, which sizes to generate, what to load first, and, most consequentially, where in your stack the processing happens so that it keeps happening after launch day.
This matters to anyone who owns a website's results. Images are usually the heaviest thing on a page and the usual cause of a poor Largest Contentful Paint, the Core Web Vitals metric that measures when the main content appears. Marketers feel it as bounce on mobile landing pages, e-commerce teams feel it on product pages, and developers feel it every time an editor uploads a twelve-megapixel photograph straight from a phone. The good news is that the fix is mechanical rather than creative: once the right pipeline is in place, nobody has to think about it on a per-image basis.
This guide is written as a decision framework. It sets out the four decisions that matter, the criteria for judging them, a scored comparison of the three realistic ways to build an image pipeline, a worked example with real pixel arithmetic, and a recommendation for each common situation. If you only need the bottom line, skip to the verdicts; if you are the person who has to implement it, the detail in between is where the work gets done.
The four decisions behind image optimization for the web
Most advice about image performance arrives as a list of tips. Lists are useful, but they hide the fact that the tips depend on each other. Serving AVIF does little good if the AVIF is three times wider than the slot it fills. Perfect responsive sizes do little good if the hero image is lazy-loaded and the browser waits to discover it. It is more useful to see the work as four separate decisions, each with its own options and its own failure modes.
- Format. Which encodings you produce for each image: AVIF, WebP, JPEG, PNG, or SVG for vector artwork, and which one acts as the fallback.
- Size. Which pixel widths you generate, and how the browser is told to choose between them, using srcset with sizes, or the picture element when the crop changes between layouts.
- Loading behavior. Which images load eagerly and with high priority, which ones are lazy-loaded, and how the page reserves space for them so the layout does not jump.
- Pipeline. Where the conversion and resizing actually happen: when a file is uploaded to the CMS, when the site is built, or on request through an image CDN.
The first three decisions are largely settled by current browser capabilities and published guidance, and this article states the defaults plainly. The fourth decision is where teams genuinely differ, because it depends on the platform, the size of the image library, who uploads images, and how much operational work the team is willing to own. That is why the scored comparison later in the article focuses on the pipeline.
The criteria that decide between options
Before comparing anything, agree on what "better" means for your site. These are the criteria used throughout this guide, and they apply to every one of the four decisions.
Bytes delivered for the quality you need
The first criterion is the obvious one: how many bytes reach the visitor's device for an image that looks acceptable in its slot. This is a function of format, pixel dimensions and compression settings together. Pixel dimensions are usually the biggest lever. A format switch might save a meaningful fraction of the file; serving an image at one quarter of the pixel count saves roughly three quarters of the data before format even enters the picture.
Effect on Largest Contentful Paint and layout stability
Bytes are a proxy. What visitors experience is how quickly the main content appears and whether the page jumps while it loads. Google's guidance on web.dev sets a "good" Largest Contentful Paint at 2.5 seconds or less and a "good" Cumulative Layout Shift at 0.1 or less, both measured at the 75th percentile of real page loads. On most content and commerce pages, the LCP element is an image, so image decisions directly move this number. Discovery and priority matter here as much as file size: a small image that the browser finds late can still produce a slow LCP.
Resistance to human error
A pipeline that depends on someone remembering to export at the right size will fail, not because people are careless but because they are busy. The best setups make the correct outcome the default: editors upload whatever they have, and the system produces the right derivatives regardless. This criterion weighs heavily in the pipeline comparison.
Operational cost and complexity
Every approach has a running cost, whether that is compute at build time, storage for derivatives, a subscription to an image service, or developer time maintaining scripts. The costs vary enormously by traffic and library size, so this guide does not quote prices; instead it identifies what drives the cost for each option so you can estimate it for your own situation.
Control and portability
Finally, how much control you keep over encoder settings and output, and how hard it would be to move away. Some options produce plain files you own outright. Others tie your image URLs to a vendor's transformation syntax, which is convenient until you want to leave.
Decision one: which image formats to serve
The settled answer is to serve AVIF or WebP with a fallback, rather than one format for everybody. AVIF typically delivers a substantial saving over JPEG at equivalent visual quality, though the size of that saving varies from image to image and depends heavily on the encoder settings used. WebP sits between the two, with near-universal browser support and fast encoding. JPEG remains the safe fallback for photographs, PNG for images that need lossless reproduction or transparency in environments where the modern formats are not available, and SVG for logos, icons and simple illustrations that are drawn rather than photographed.
| Format | Best used for | Strengths | Watch out for |
|---|---|---|---|
| AVIF | Photographs and complex graphics as the primary format | Usually the smallest files at a given quality; supports transparency and high bit depth | Slower to encode; quality settings are not comparable to JPEG numbers; can soften fine texture at aggressive settings |
| WebP | Primary or secondary format for photographs and transparent graphics | Broad support; fast encoding; lossy and lossless modes | Savings over well-tuned JPEG are smaller than AVIF's |
| JPEG | Fallback for photographs; email and third-party syndication | Universal support; mature encoders such as MozJPEG | No transparency; blocky artifacts at low quality |
| PNG | Screenshots, UI captures and graphics that must be lossless | Lossless; transparency | Very large files for photographs; never the right choice for a photo |
| SVG | Logos, icons, diagrams and flat illustrations | Resolution-independent; tiny for simple artwork; stylable with CSS | Unsuitable for photographs; files exported from design tools often need cleaning |
How the browser chooses a format
There are two mechanisms. In markup, the picture element lists source elements with a type attribute, such as image/avif and then image/webp, followed by an ordinary img with a JPEG. The browser takes the first source it supports. On the server side, an image CDN can read the Accept header that browsers send with image requests and return the best format the browser advertises from a single URL. If you use the server-side approach, the response must carry a Vary: Accept header, or an intermediate cache may hand an AVIF to a browser that asked for something else.
Quality settings are not portable
A frequent mistake is to set AVIF quality to the same number used for JPEG. The scales are different, and even two JPEG encoders can produce different results at the same nominal quality. The reliable method is to pick a handful of representative images, such as a portrait, a product shot on white, a landscape with foliage and a screenshot with text, encode them at several settings, and compare at the displayed size on a real screen. Objective metrics such as SSIMULACRA2 or Butteraugli can help automate the comparison across a larger sample, but a human look at the difficult images is still worth doing once. Record the settings you settle on and treat them as configuration, not as something an individual decides per upload.
Vector artwork is a separate track
Logos and icons should not go through a photographic pipeline at all. An SVG logo that is a few kilobytes will look sharp at every density, while a PNG version needs multiple sizes and still blurs when scaled. Clean SVGs with a tool such as SVGO before shipping them, and see our practical guide to SVG icons in web interfaces for sprite, inline and accessibility decisions.
Decision two: generating the sizes the layout actually uses
The single most expensive image mistake on the web is one large image scaled down by CSS for every breakpoint. A 2400-pixel-wide photograph displayed in a 360-pixel card on a phone still costs the visitor the full download and the device the full decode. The remedy is to generate a set of widths and let the browser pick, using srcset with sizes.
How srcset and sizes work together
The srcset attribute lists candidate files with their intrinsic widths, for example image-480.avif 480w, image-800.avif 800w, image-1200.avif 1200w. The sizes attribute tells the browser how wide the image will be displayed at each viewport, in CSS pixels, before the CSS has loaded. The browser multiplies the slot width by the device pixel ratio and picks the smallest candidate that covers it. Without sizes, the browser assumes the image fills the full viewport width, which overfetches for any image in a column or grid.
The sizes attribute is the part teams most often get wrong, because it has to mirror the layout. A card grid that shows one column on phones, two from 640 pixels and three from 1024 pixels inside a 1200-pixel container would have a sizes value along the lines of (min-width: 1024px) 384px, (min-width: 640px) 50vw, 100vw. When the design changes, sizes must change with it, so keep it next to the component that owns the layout rather than scattered across templates. MDN Web Docs has a clear reference on responsive images that is worth bookmarking for the syntax details.
Choosing the width ladder
Generating a derivative for every possible width is wasteful; generating only two leaves big gaps. A practical approach is a ladder of widths spaced so that each step is roughly 30 to 50 percent larger than the one before, capped at the largest size any slot will ever need at the highest pixel density you care about. For a full-width hero in a 1440-pixel design, that cap is often 2400 to 2880 pixels; for a thumbnail that never exceeds 300 CSS pixels, 600 or 900 pixels is enough. Many teams settle on something like 320, 480, 640, 800, 1024, 1280, 1600, 2000 and 2400 for full-width images, and a shorter ladder for components with known maximum widths.
When to use the picture element instead
srcset changes resolution; it does not change the crop. When the mobile layout needs a tighter crop of the same photograph, such as a portrait-orientation hero on phones and a wide panorama on desktop, that is art direction, and it calls for the picture element with media queries on each source. Our guide to the picture element and art direction covers when a crop change is worth the added complexity and how to combine it with format switching.
High-density screens and diminishing returns
Many phones have device pixel ratios of 3. Serving a full 3x image to every such phone is often unnecessary: at typical viewing distances, the difference between 2x and 3x on a photograph is hard to see, while the pixel count rises by more than half again. Capping the effective density at about 2x for photographs is a reasonable trade that some teams adopt deliberately, either by limiting the largest candidate in srcset or by letting an image CDN apply a density cap. Keep full density for images containing fine text or line art, where softness is noticeable.
Decision three: loading behavior and layout stability
Once format and size are right, the remaining lever is when each image loads and how the page makes room for it. Get this wrong and a perfectly compressed hero image can still produce a failing LCP.
Above the fold: load eagerly and signal priority
The image likely to be the LCP element, usually a hero or the main product photo, should load eagerly, which is the default, and should be marked with fetchpriority="high" so the browser requests it ahead of less important resources. It should also be discoverable in the initial HTML. An image set as a CSS background, or injected by JavaScript after hydration, is invisible to the browser's preload scanner, so it starts late no matter how small it is. If the LCP image genuinely has to be a background image, a preload link with imagesrcset and imagesizes attributes can restore early discovery, but a plain img element in the markup is simpler and less fragile.
Below the fold: lazy-load
Images further down the page should use loading="lazy", which tells the browser to defer the request until the image approaches the viewport. This saves bandwidth for visitors who never scroll and frees the network for the resources that matter first. The rule has one hard edge: never lazy-load the hero. Lazy-loading an above-the-fold image delays its request until layout has been calculated, which is one of the most common and most avoidable causes of a slow LCP.
Reserve the space
Every image needs explicit width and height attributes, or a CSS aspect-ratio, so the browser can reserve the right amount of space before the file arrives. Modern browsers compute the aspect ratio from the width and height attributes even when CSS makes the image fluid, so setting them costs nothing and prevents the layout shift that happens when text below an image is pushed down as it loads. This is the single cheapest improvement to Cumulative Layout Shift on most sites.
Decoding and placeholders
The decoding="async" attribute lets the browser decode large images off the main thread, which can help on image-heavy pages. Low-quality placeholders, whether a blurred tiny version or a dominant-color background, improve perceived loading for below-the-fold galleries, but they should never replace the real LCP image, and inline base64 placeholders add weight to the HTML. Use them where they help and keep them small.
Alternative text is part of the job
Optimization is not only about bytes. Every meaningful image needs alt text that conveys its purpose, and decorative images should carry an empty alt attribute so screen readers skip them. Build the alt field into the upload form rather than leaving it for later. Our article on web accessibility conformance, done properly sets out how image alternatives fit into a wider WCAG program.
Decision four: where the processing happens
With the defaults for format, size and loading agreed, the real decision is the pipeline: the machinery that turns an uploaded original into the right set of files, every time, without anyone checking. There are three realistic options. A fourth, exporting by hand from a design tool, is not really an option for any site with more than a handful of pages, because it relies entirely on individual discipline.
Option A: processing at upload time in the CMS
In this model, the CMS or application generates derivatives when an editor uploads a file. WordPress is the familiar example: it creates intermediate sizes on upload, writes srcset and sizes into image markup automatically, and has supported WebP uploads since version 5.8 and AVIF since 6.5, subject to the server's image library supporting them. It also downsizes very large originals above a threshold, which is 2560 pixels by default. Custom applications can do the same with a job queue and a library such as sharp or libvips, writing derivatives to object storage when the upload completes.
Pros
- Compresses at the point of upload, so an editor cannot accidentally publish a 6MB photograph
- Output is plain files you own and can move between hosts
- No per-request cost; derivatives are served as static files from your CDN
- Fits naturally into CMS workflows editors already understand
Cons
- Changing the width ladder or format means reprocessing the whole existing library
- Output quality depends on the server's image library and its version, which is easy to overlook on shared hosting
- Plugin-based conversion is often configured once and never checked again
- Storage grows with every size and format generated
The weak point of upload-time processing is drift. Settings chosen at launch persist long after the layout has changed, and nobody notices that the theme now displays images at 1400 pixels while the largest derivative is 1024. Budget time for a periodic audit and for regenerating derivatives when the design changes. For WordPress sites built with custom blocks, the block is the right place to own the sizes attribute; see WordPress block development: the decisions that matter.
Option B: processing at build time
Static site generators and modern front-end frameworks can process images during the build. Eleventy Image, Astro's image tooling and similar components in other frameworks take a source file, produce the configured widths and formats, and emit the complete picture or img markup with dimensions filled in. Because the markup and the files come from the same step, the sizes attribute, the dimensions and the derivatives stay consistent by construction.
Pros
- Markup and files are generated together, so dimensions and srcset are always correct
- Encoder settings live in version-controlled configuration and can be reviewed like code
- Plain static output with no runtime dependency or per-request cost
- Easy to test: a build can fail if an image exceeds a size budget
Cons
- Build times grow with the library; AVIF encoding in particular is slow without caching between builds
- Poorly suited to images uploaded by editors or users after deployment
- Requires developer involvement for every change to image handling
- Large libraries need a persistent cache of processed images to keep builds practical
Build-time processing is at its best when images are part of the codebase or change on the same cadence as deployments: marketing sites, documentation, portfolios. It struggles where content changes hourly. If your builds already run through a deployment pipeline, our guide to Laravel deployment optimization covers caching build artifacts between releases, a principle that applies equally to processed images.
Option C: an image CDN with on-the-fly transformation
An image CDN stores the original and generates derivatives on request, based on parameters in the URL or on the Accept header. Services in this category include Cloudinary, imgix, Cloudflare Images and the image optimization features of general CDNs such as Fastly. The first request for a given size and format is transformed and cached at the edge; subsequent requests are served from cache.
Pros
- Changing sizes or formats is a URL change, with no library reprocessing
- Automatic format negotiation serves AVIF, WebP or JPEG from one URL
- Handles user-generated and editor-uploaded images equally well
- New formats can be adopted when the vendor supports them, without redeploying
Cons
- Recurring cost that scales with transformations, bandwidth or stored originals, depending on the vendor's pricing model
- Image URLs become tied to one vendor's syntax, which makes migration harder
- Uncached first requests are slower, which matters for rarely viewed images
- Defaults such as automatic quality need verifying, not trusting
An image CDN is the most flexible option and often the fastest to adopt on an existing site, because it can sit in front of the current media library. The long-term cost is lock-in: if every template builds URLs with vendor-specific parameters, moving away means rewriting those templates. A thin helper function that builds image URLs from neutral parameters, such as width, format and quality, contains that risk to one file.
Scoring the three pipelines against the criteria
The scorecard below rates each pipeline from 1 (weak) to 5 (strong) on the criteria set out earlier. The scores reflect typical implementations, not the best or worst possible; a carefully built upload pipeline can outperform a carelessly configured image CDN. Use the scores to frame the conversation, then adjust them for your own platform and team.
| Criterion | A: Upload-time (CMS) | B: Build-time | C: Image CDN |
|---|---|---|---|
| Bytes for quality (format and size control) | 3 | 5 | 5 |
| Markup correctness (dimensions, srcset, sizes) | 3 | 5 | 3 |
| Resistance to editor error | 4 | 2 | 5 |
| Handles post-launch and user uploads | 5 | 1 | 5 |
| Ease of changing sizes or formats later | 2 | 3 | 5 |
| Running cost predictability | 5 | 4 | 3 |
| Control and portability | 4 | 5 | 2 |
| Total (out of 35) | 26 | 25 | 28 |
The totals are close, and that is the honest result: there is no universally best pipeline. What the table does show is where each option is weak. Build-time processing is excellent until content is uploaded after deployment. An image CDN is excellent until you need to leave it or predict next year's bill. Upload-time processing is solid and cheap but degrades quietly as the design moves on. The right choice is the one whose weakness matters least for your site, which is why the recommendations later in this guide are organized by situation.
A note on markup correctness for the image CDN: the CDN produces the files, but your templates still have to write correct sizes and dimensions. Teams that adopt an image CDN and assume the job is done often ship perfect files into markup that still requests the wrong width.
A worked example: a product page hero and gallery
To make the arithmetic concrete, consider an illustrative product page on an online store. The figures are chosen to be realistic, not taken from a specific client. The design has a full-width hero at the top, a product gallery of six images in a two-column grid on desktop, and a row of four related-product thumbnails.
Starting point
The merchandising team uploads photographs straight from a camera at 6000 by 4000 pixels, which is 24 megapixels. The theme displays the hero in a container that is at most 1200 CSS pixels wide, and scales the same file down with CSS at every breakpoint. The gallery images and thumbnails use the same originals. Every visitor, on every device, downloads eleven 24-megapixel JPEGs, and each is typically several megabytes.
Sizing the hero
The largest slot is 1200 CSS pixels. At a device pixel ratio of 2, that is 2400 device pixels, so the ladder for the hero caps at 2400 pixels wide. A 2400 by 1600 derivative is 3.84 megapixels, which is 16 percent of the original's pixel count. On a phone 390 CSS pixels wide at a device pixel ratio of 3, the slot needs 1170 device pixels, so the browser picks the 1280-pixel candidate from a ladder of 480, 800, 1280, 1600, 2000 and 2400. That 1280 by 853 file is about 1.1 megapixels, under 5 percent of the original. The hero markup uses a picture element with an AVIF source, a WebP source and a JPEG img fallback, each with the same srcset widths, a sizes value of (min-width: 1200px) 1200px, 100vw, explicit width and height attributes of 2400 and 1600, and fetchpriority="high". It is not lazy-loaded.
Sizing the gallery and thumbnails
The gallery cells are at most 580 CSS pixels wide on desktop and full width on phones. The ladder here is 480, 800 and 1200 pixels, with a sizes value of (min-width: 1024px) 580px, 100vw. The thumbnails never exceed 280 CSS pixels, so they need only 280 and 560-pixel candidates. All ten images below the hero use loading="lazy", explicit dimensions and decoding="async". Only the gallery images that appear above the fold on desktop, typically the first two, are left eager; the rest wait until the visitor scrolls.
What changes
| Image | Before (pixels served) | After, phone at 3x (pixels served) | After, desktop at 2x (pixels served) |
|---|---|---|---|
| Hero | 24.0 MP | 1.1 MP (1280 wide) | 3.8 MP (2400 wide) |
| Each gallery image | 24.0 MP | 0.96 MP (1200 wide) | 0.96 MP (1200 wide) |
| Each thumbnail | 24.0 MP | 0.21 MP (560 wide) | 0.21 MP (560 wide) |
| Loaded before scrolling | All 11 images | Hero only | Hero and first two gallery images |
The pixel reduction alone is more than an order of magnitude for every image on the page, before a format change saves anything further. Switching the delivered format to AVIF, with WebP and JPEG as fallbacks, reduces the bytes again by an amount that varies by photograph. The loading changes mean a phone visitor who never scrolls downloads one image instead of eleven. The effect on LCP comes from both directions: the hero file is far smaller, and the browser requests it first because it is discoverable in the HTML and marked with high priority.
Verdict For a store with a steady flow of new product photography, this example points to an upload-time pipeline or an image CDN, not build-time processing. The originals keep arriving after deployment, and the whole benefit depends on derivatives existing for every new product the day it goes live.
For stores, image weight on product and cart pages feeds directly into conversion work. Our checkout optimization service treats page speed on the path to purchase as one of the variables it tests.
Recommendations by situation
The scorecard shows that the options trade off against one another. The recommendations below apply those trade-offs to the situations we see most often. Each assumes the defaults for format, size and loading from the earlier sections; the difference is where the work happens.
A content or brochure site on a standard CMS
A marketing site on WordPress or a similar CMS, with a small team of editors uploading a few images a week, is well served by processing at upload time. The CMS already has the hooks, the output is plain files, and there is no recurring cost. The work is in configuration: define intermediate sizes that match the theme's actual slots, make sure the server's image library supports AVIF or WebP output, confirm that the sizes attribute the theme writes reflects the layout, and set up a way to regenerate derivatives when the design changes.
Verdict Use upload-time processing, verify the server's image library supports your target formats, and schedule a check of the output every time the theme changes. Add an image CDN only if the team later needs formats or sizes the server cannot produce.
A static or framework-built marketing site maintained by developers
Where images are committed to the repository and change when the site is deployed, build-time processing is the cleanest answer. Configuration lives in code, markup and files are generated together, and a build can enforce budgets. The things to plan for are build duration, which needs a persistent cache of processed images, and any section of the site, such as a blog, where non-developers need to add images between deployments. Those sections may need a CMS with upload-time processing or an image CDN alongside the build.
A store, marketplace or platform with frequent uploads
When images arrive continuously, whether from merchandisers, vendors or users, and the catalog runs to thousands of products, an image CDN earns its cost. It handles every new upload identically, negotiates format per browser, and lets the team change the width ladder without reprocessing a large library. The trade is recurring spend and vendor dependency, both of which can be managed: model the cost against your traffic before committing, and route all image URLs through a single helper so the vendor can be replaced.
Verdict For high-volume or user-generated imagery, use an image CDN with automatic format negotiation, wrap its URL syntax in one helper function, and keep the originals in storage you control so a future migration is a configuration change rather than a data recovery project.
An existing site with a large unoptimized library
Sites that have run for years often carry tens of thousands of oversized originals. Reprocessing them through an upload-time pipeline is possible but slow and needs careful batching; putting an image CDN in front of the existing library produces results quickly and can be a bridge while a longer-term pipeline is built. Either way, fix the upload path first so the problem stops growing, then work backward through the library in order of traffic.
Mistakes that undo the work
Most image problems we are asked to fix are not exotic. They are the same few mistakes, repeated because nobody checked the output after the initial setup.
- One large image scaled down by CSS for every breakpoint. The CSS makes it look right and hides the cost completely. Check the network panel for image files whose intrinsic width is far larger than their rendered width.
- Lazy-loading the hero image. Often caused by a theme or plugin that applies loading="lazy" to every image indiscriminately. The first image in the content area, and anything above the fold, should be eager.
- PNG for photographs. A photograph saved as PNG can be many times the size of the same image as a well-compressed JPEG, and far larger than AVIF. PNG belongs to screenshots and graphics that need lossless reproduction.
- Leaving optimization to a plugin nobody has checked the output of. Plugins fail quietly: an API quota runs out, a server library lacks AVIF support, or a setting is changed during an update. Open a page, inspect the images actually delivered, and confirm format, dimensions and file size at least once a quarter.
- A sizes attribute that no longer matches the layout. After a redesign, stale sizes values make the browser choose candidates that are too large or too small. Treat sizes as part of the component, and review it whenever the component's layout changes.
- Missing width and height. Without them, the page shifts as images arrive, which harms Cumulative Layout Shift and frustrates readers who have started reading.
- The LCP image hidden from the preload scanner. A hero set as a CSS background or rendered only after JavaScript runs is discovered late. Put it in the HTML as an img element.
Images are also only one part of what loads above the fold. Web fonts compete for the same early bandwidth, and a heavy font strategy can delay rendering as surely as a heavy hero; web typography: what actually works covers subsetting and preloading choices that pair well with the image work described here.
Checking the output and knowing when to bring in help
An image pipeline is only as good as its output, and output drifts. The verification routine does not need to be elaborate, but it does need to exist.
Lab checks
Lighthouse and PageSpeed Insights flag oversized images, missing dimensions, offscreen images that are not lazy-loaded, and the LCP element with its timing breakdown. The breakdown matters: it separates time to first byte, resource load delay, resource load duration and render delay. A long load delay points to discovery or priority problems; a long load duration points to file size. In the browser's network panel, filter by image and compare each file's intrinsic dimensions with the size it renders at.
Field checks
Lab tests run on one device and one connection. Real visitors do not. Field data, from the Chrome User Experience Report or from your own collection with the web-vitals JavaScript library, shows LCP at the 75th percentile across real devices and can identify which element was the LCP on slow loads. Our guide to field debugging with the web-vitals library explains how to capture attribution data so you can see whether images are the cause. For context on how the wider web is doing, the HTTP Archive Web Almanac publishes annual analysis of image formats, sizes and loading practices across millions of sites, which is useful for setting expectations with stakeholders.
Automated guardrails
The most reliable protection is to make regressions fail loudly. A build step can reject images over a byte budget; a CMS can refuse uploads above a pixel threshold or downscale them automatically; a scheduled test can run Lighthouse against key templates and alert when LCP or image weight crosses a line. Guardrails turn a one-off optimization project into a property of the system.
When to bring in help
Three situations usually justify outside help. The first is a large existing library that needs reprocessing, where batching, storage, URL preservation and cache invalidation need planning so that the site stays up and nothing breaks. The second is editors who keep uploading unoptimized files despite guidance, which is a sign that the pipeline, not the people, needs changing. The third is a failing Largest Contentful Paint where images are the cause and the obvious fixes have already been tried. Our web performance and accessibility team handles all three, from auditing what a site actually delivers to building the pipeline that keeps it right.
If your LCP is failing and the LCP element is an image, fix discovery and priority first, sizing second and format third. Those three changes, in that order, resolve most image-driven LCP problems without touching the design.
Where this comes from
- web.dev — Fast load times and image optimization
- MDN Web Docs — Responsive images
- HTTP Archive Web Almanac — Media
The figures and practices above come from the sources listed.
Working on something like this?
We take on Web Design & Development work for teams who want it done once, properly. Tell us what you are building and we will tell you honestly whether we are the right studio for it. Start a project.
Where to go next
Spotted something wrong? Report an error on this page. We correct on the page and say what changed.