How do AVIF, WebP, and srcset compound into a fast image pipeline? #
Images dominate page weight on most marketing sites. One oversized hero can outweigh everything else combined: markup, styles, scripts, fonts. The fix is not one trick. It is a pipeline with four layers, each multiplying the others.
Modern formats with fallbacks. Responsive file selection. Hashed immutable caching. Lazy loading below the fold. Get all four right and pages feel instant on phones that used to choke. Skip any one and the rest leak.
Think of images as luggage for a trip. Pack each bag sized to its journey, tag it so it never gets lost, and leave the bags you will not need until later at the hotel. That is the whole guide in one image. Now the details.
| Layer | What it does | How to check it |
|---|---|---|
| Format | Serve AVIF first then WebP then JPEG fallback | Look at network panel and content type |
| Responsive | Use srcset plus sizes to match layout | Throttle to phone width and watch bytes |
| Caching | Hash filenames and cache immutable for a year | Check cache headers on a reload |
| Lazy load | Defer below fold and keep eager above fold | Scroll and watch when images request |
| Alt and stability | Set width height and descriptive alt | No shift on load and screen reader reads cleanly |
How do you choose the right format? #
Different pixels compress differently. The web.dev format guide walks the tradeoffs; here is the working version.
AVIF goes first for photographs. Built on AV1 video coding, it compresses photos smaller than anything else at matching visual quality. Support has crossed into safe territory: Can I Use reports about 95% global AVIF support across current browsers. That number makes AVIF-first a default, not a gamble.
WebP stands behind it as the wide fallback. It beats legacy JPEG substantially on photos, handles transparency, and even animates. Browsers without AVIF almost always speak WebP.
JPEG or PNG closes the cascade. JPEG remains the universal photographic fallback for the last stragglers. PNG serves logos, icons, and graphics where edges must stay crisp or transparency must stay lossless. SVG joins for anything drawn as vectors: logos and diagrams stay sharp at every size for a fraction of a raster file.
Serve the cascade with the picture element so each browser takes the first format it understands:
<picture>
<source srcset="hero-1280.avif 1280w, hero-800.avif 800w" type="image/avif" />
<source srcset="hero-1280.webp 1280w, hero-800.webp 800w" type="image/webp" />
<img
src="hero-800.jpg"
srcset="hero-1280.jpg 1280w, hero-800.jpg 800w"
sizes="(max-width: 640px) 100vw, 1280px"
width="1280"
height="720"
alt="Pottery workshop table covered in clay bowls"
loading="eager"
fetchpriority="high"
/>
</picture>Keep transparency needs explicit in your head: AVIF and WebP both handle it, JPEG never does. Reserve PNG for graphics where lossless edges matter, never for full-bleed photos. And keep the final fallback until your own analytics show it truly unused. Someone's old tablet will thank you.
Try it: Favicon Generator
How do you serve responsive sizes with srcset? #
A phone on a narrow viewport must never download a desktop hero. That sentence describes an enormous share of wasted mobile bytes in the wild.
Responsive images fix it with two attributes working as a pair. The srcset lists candidates with width descriptors. The sizes describes how wide the image renders at each breakpoint. The browser does the math and fetches the smallest candidate that still renders sharply. MDN's img reference documents both attributes precisely, including the sizes syntax most people guess at.
Match candidate widths to your actual layout breakpoints, not round numbers that feel nice. A 640px phone slot wants a 640 or 800 wide file, not a 1920 wide masterpiece. Generate three or four widths per visual: small, medium, large, and the full glory version. Pair every set with the format cascade above so old browsers also get responsive choices, just in older formats.
Then audit with device emulation. Open dev tools, throttle to a phone viewport, reload, and check which file actually downloaded. A wrong sizes value silently defeats the system: the browser trusts your description, fetches the giant file, and nobody errors. Verification takes two minutes. Skip it and the pipeline is decoration.
Why cache hashed assets immutably? #
Repeat visits should barely download. Far-future caching makes that true, but only content-hashed filenames make it safe.
The pattern: append a content hash to each built asset name, serve hashed files with a long-lived immutable directive, and keep HTML short-lived so updated references propagate instantly. Changed image, new URL, fresh download exactly once. Unchanged image, same URL, served from cache for a year.
Never aim immutable caching at unhashed filenames. Visitors would keep stale copies with no expiry and no escape hatch. This is why generated sites with hashed build outputs feel fast on the second visit: the browser keeps every unchanged file and refetches only what actually changed.
A practical checklist for the build: hash every image the bundler emits, set immutable year-long caching on hashed paths, keep HTML cache short, and confirm a redeploy with one changed image only invalidates that image. Cache discipline is invisible when right and infamous when wrong.
What we learned building this? #
BYOB projects serve assets through Cloudflare with Vite hashed filenames plus immutable caching plus responsive image handling in the generated SvelteKit markup. Storage for uploads flows through R2 as described in https://byob.studio/blog/byob-storage-r2 while image choice uses AVIF first WebP second with JPEG fallback. The pipeline advice matches how we keep our own tool pages light such as https://byob.studio/tools/og-image-maker which must load fast on mobile. Lazy loading with explicit width height prevents shift.
Who this is for (and who should skip it)? #
This fits makers shipping marketing pages where one hero can outweigh everything else. If you control format srcset caching and lazy loading you can cut bytes without losing sharpness.
Skip perfection if your pages are text heavy and images are small. Serve WebP plus JPEG fallback and move on until image weight dominates your real field data.
One limit to know. AVIF encodes slower and a wrong sizes value silently fetches oversized files, so verify on a phone viewport. Text heavy pages gain little, so stop at WebP plus fallback until images dominate field data.
- Best for developers shipping responsive AVIF and WebP images with correct srcset sizes.
- Best for agencies speeding up client marketing sites on phones without losing quality.
- Best for small business owners fixing heavy hero images that slow mobile loads.
Load lazily without shifting layout #
Below-the-fold images should wait their turn. Lazy loading defers them until the user approaches, cutting initial payload and speeding first paint. The hero and anything above the fold loads eagerly with high fetch priority. Everything below gets loading="lazy".
The trap is layout shift. A lazy image with no reserved space collapses to zero height, then pops the page down when it arrives. Readers lose their line. Google's Core Web Vitals program measures exactly this instability as Cumulative Layout Shift, and real users feel it before any metric names it.
The fix is one habit: always declare width and height, or an aspect-ratio box, so the browser reserves space before bytes arrive. MDN is blunt about why: dimensions let the browser compute aspect ratio up front and hold the slot. Pair that with descriptive alt text on every image regardless of strategy, because accessibility and indexing never lazy-load.
Pre-launch, walk this list: AVIF plus WebP sources with fallback on key visuals, srcset widths matched to layout slots, hashed filenames with immutable caching, hero eager with everything below lazy and dimensioned, alt text meaningful, files compressed, mobile payload verified on a real phone viewport.
Pack the right bags, tag them well, and leave the late ones at the hotel. Your visitors arrive to a page that is already ready.