A website image optimization checklist should test the files that a browser downloads from your deployed page. The source image, responsive markup, layout dimensions, loading priority, and alternative text all affect the result. A compressed file can still waste bytes if the browser downloads a 2400-pixel image for a 400-pixel card.
Use the production URL for this check. Build tools and image CDNs often transform files after local development, while a browser chooses one candidate from srcset according to the viewport and device pixel ratio. Record the selected URL, transferred bytes, rendered size, and accessible text so another developer can reproduce each finding.
Website image optimization checklist for production
Review images in the page's first screen and in the main user path. Start with the hero or other Largest Contentful Paint candidate, then inspect content images, logos, and linked graphics.
- Match each source width to its rendered size and expected screen density.
- Give responsive images accurate
srcsetandsizesvalues. - Pick a format based on measured file size and visual quality.
- Add
widthandheightso the browser can reserve the right aspect ratio. - Load the main visual without delay and defer off-screen images.
- Give informative images useful alternative text and decorative images an empty
altvalue. - Test the image request, selected candidate, layout, and accessibility output on the deployed page.
Google's image SEO guidance recommends standard HTML image elements, responsive sources, supported formats, and useful alt text. These practices also help browsers and assistive technology interpret the page without guessing.
Match image dimensions to the rendered box
Start with the difference between an image's intrinsic dimensions and its rendered dimensions. A product card that displays an image at 360 by 240 CSS pixels does not need a 2400 by 1600 source on a normal-density screen. High-density displays need more source pixels, so account for window.devicePixelRatio before treating every larger file as waste.
Open the browser console on the deployed page and inspect the images the browser rendered:
[...document.images].map((image) => ({
url: image.currentSrc,
rendered: `${Math.round(image.getBoundingClientRect().width)}x${Math.round(image.getBoundingClientRect().height)}`,
intrinsic: `${image.naturalWidth}x${image.naturalHeight}`,
density: window.devicePixelRatio,
alt: image.getAttribute("alt"),
}));
Compare naturalWidth with rendered width multiplied by the display density. Allow some margin for responsive breakpoints and cropping. Large gaps deserve investigation because the visitor pays the transfer and decode cost even when CSS draws a small box.
Resize the source files or use an image transformation service to create a bounded set of widths. Keep the original in your media pipeline, not as the default file sent to each visitor.
Build responsive image markup
The browser needs source candidates and an accurate estimate of the layout width. srcset lists the files, while sizes describes how wide the image will render at each breakpoint:
<img
src="/images/audit-dashboard-960.webp"
srcset="
/images/audit-dashboard-480.webp 480w,
/images/audit-dashboard-960.webp 960w,
/images/audit-dashboard-1440.webp 1440w
"
sizes="(max-width: 720px) 100vw, 720px"
width="1440"
height="900"
alt="Audit report showing failed metadata and accessibility checks"
>
The MDN `img` reference explains how the browser combines width descriptors with sizes to choose a source. Keep the src fallback, and make each width descriptor match the file's intrinsic width.
Test the choice in browser developer tools at a narrow mobile width and a desktop width. The Network panel shows the file that the browser requested. Disable the cache when changing breakpoints because a browser can reuse a larger candidate that it has already downloaded.
Use <picture> when the composition or format must change. A cropped mobile image and a wide desktop image represent art direction; three copies of the same photo at different widths belong in srcset. The web.dev responsive images guide covers both cases and recommends choosing formats according to the image content.
Compare WebP, AVIF, JPEG, PNG, and SVG
WebP and AVIF often reduce raster image bytes, but the file extension does not prove that the result is smaller or sharper. Export representative candidates at acceptable quality, then compare the actual response sizes and visual output.
- Use SVG for logos, icons, and diagrams that remain vector artwork.
- Compare AVIF, WebP, and JPEG for photographs or detailed raster artwork.
- Keep PNG when lossless pixels or alpha behavior justify the extra bytes.
- Use
<picture>when you need format fallbacks for the browsers in your support policy.
Do not rename a JPEG file to .webp. Check the response Content-Type and decode the file in a browser. A proxy that returns HTML at an image URL can produce a successful status while leaving the image broken.
Run a header check against the selected source:
curl -sSIL https://example.com/images/audit-dashboard-960.webp
Confirm the final status, Content-Type, cache policy, and final URL. Stable cacheable image URLs reduce repeat transfer, but a long cache lifetime requires a versioning plan when the asset changes.
Prevent image layout shifts
Add truthful width and height attributes to each <img>. The browser uses their ratio to reserve space before the file arrives, while CSS can still make the image responsive:
img {
max-width: 100%;
height: auto;
}
MDN recommends both dimensions so the browser can allocate space before loading the image. The web.dev CLS guide shows how missing dimensions can move text and controls after an image appears.
Test pages with a cold cache and a throttled connection. Watch for content that moves below images, late aspect-ratio changes, and placeholders whose ratio differs from the final file. Dynamic media components should preserve the final ratio from the first render.
The Core Web Vitals guide for developers explains how to read lab and field CLS instead of treating one local run as proof of user performance.
Load the main image at the right time
Avoid loading="lazy" on the image that becomes the page's LCP element. Lazy loading can delay discovery until layout, which makes the main visual appear later. The web.dev LCP guidance recommends making the LCP resource discoverable in the initial HTML and checking its priority in developer tools.
Use native lazy loading for images that begin outside the viewport:
<img
src="/images/report-detail-720.webp"
width="720"
height="480"
loading="lazy"
alt="Finding detail with evidence and a suggested fix"
>
Measure before adding fetchpriority="high" or a preload. Reserve those hints for the main candidate because competing high-priority requests can delay CSS, fonts, or other critical work. The mobile website testing guide provides a short workflow for checking the first screen and its transfer cost on a narrow viewport.
Write alt text for the image's purpose
An alt attribute is part of the image contract, but its value depends on context. Describe information that the image contributes to the page. Use alt="" for decoration or for an image whose meaning nearby text already supplies.
The W3C Web Accessibility Initiative publishes an alt decision tree for informative, functional, decorative, and complex images. A linked logo may need the link's destination or function. A chart needs a short alternative plus the underlying values or conclusion in nearby text. Repeating a caption word for word adds noise for a screen-reader user.
Google also uses alt text with page context to understand an image. Write for the person who cannot see the file, and skip keyword lists. The accessibility checks before launch cover labels, focus, headings, and the limits of automated evidence beyond images.
Add responsive image testing to CI
A browser test can flag missing alt attributes and source files that exceed your chosen density budget. Set the budget for your design system instead of copying a threshold from another site:
import { test, expect } from "@playwright/test";
test("production images match the page contract", async ({ page }) => {
await page.goto("https://example.com/");
const issues = await page.locator("img").evaluateAll((images) =>
images.flatMap((image) => {
const renderedWidth = image.getBoundingClientRect().width;
const allowedWidth = renderedWidth * window.devicePixelRatio * 1.25;
const result: string[] = [];
if (!image.hasAttribute("alt")) result.push(`${image.currentSrc}: missing alt`);
if (renderedWidth > 0 && image.naturalWidth > allowedWidth) {
result.push(`${image.currentSrc}: ${image.naturalWidth}px source for ${Math.round(renderedWidth)}px box`);
}
return result;
}),
);
expect(issues).toEqual([]);
});
Run the test at the viewports your product supports. Add request-size assertions in the layer that owns image transformation because browser cache state and compression headers affect transferred bytes. The website regression testing checklist shows how to keep production evidence tied to a release and compare it after deployment.
Run a website image audit with Slop Audit
Run a Slop Audit on the public URL after deployment. The browser stage compares rendered and intrinsic image dimensions, counts image URLs that use AVIF or WebP, and reports images with no alt attribute. The report also records page-level request and transfer totals plus lab LCP and CLS when the browser run can measure them.
The audit does not compress files, judge visual quality, inspect each route, or prove that every alt value fits its context. It also cannot replace field Core Web Vitals data. Use its URL, viewport, selector, and performance evidence to find the first release issue, fix it in the owned image pipeline, then rescan.
Image optimization release checklist
- Test the final HTTPS page at supported mobile and desktop widths.
- Compare intrinsic dimensions with the rendered box and device density.
- Verify
srcset,sizes, fallbacksrc, and the source selected by the browser. - Measure format candidates instead of assuming that AVIF or WebP wins.
- Include accurate dimensions and preserve the same ratio in placeholders.
- Keep the LCP image discoverable without lazy loading; defer off-screen media.
- Give each
<img>an alt value that matches its purpose. - Check statuses, content types, cache rules, transfer bytes, LCP, and CLS after deployment.
- Save the checks in CI with thresholds owned by your team.
Finish the image pass before release, then use the website launch checklist for developers to check metadata, crawl controls, links, and the page's main task.