Edge‑era Image Delivery — CDN Design 2025
Published: Sep 22, 2025 · Reading time: 4 min · By Unified Image Tools Editorial
To grow search traffic, fast image delivery is non‑negotiable. This guide organizes edge/CDN design points by use case and provides a checklist to avoid common production pitfalls.
Image CDN fundamentals
- Define transformation units (origin vs transformed variants)
- Cache key definition (URL,
Accept
,Accept-Encoding
, DPR, etc.) - Expiration and invalidation (fingerprint,
Cache-Control
,stale-while-revalidate
) - Coordination with responsive images (
srcset
/sizes
correctness)
Internal links: srcset design basics, INP‑focused delivery, Priority hints & preload
HTTP headers in practice
Cache-Control: public, max-age=86400, stale-while-revalidate=259200
Vary: Accept, DPR
Accept-Ranges: bytes
Timing-Allow-Origin: *
- Use
Vary: Accept
to switch AVIF/WebP/JPEG - If you add
Vary: DPR
, generate/cache variants per DPR on the server - For SSG/ISR sites, explicit URL versioning is safest (e.g.,
hero-640.avif?v=20250922
)
Priority Hints / Early Hints
<!-- For LCP candidates -->
<link rel="preload" as="image" href="/images/hero-1200.avif" imagesrcset="..." imagesizes="(min-width: 1024px) 1200px, 90vw" fetchpriority="high" />
- Don’t mark everything as high priority (can fight CLS budgets)
- If available, send 103 Early Hints to preconnect/preload sooner
Split edge vs origin transforms
- Edge: high‑frequency, width/quality/format negotiation (AVIF/WebP)
- Origin: higher‑cost, fidelity‑critical steps (metadata edits, ICC, alpha compositing)
Tools: Format converter, Bulk compression, Placeholder generator
Classic pitfalls
Vary
set but CDN not caching (double‑config issues)- Returning AVIF to legacy clients without
Accept: image/avif
→ broken indexes - Double‑transform by both optimizer service and app CDN → quality loss
Checklist (persistent)
- [ ] LCP images: correct
fetchpriority
andsizes
- [ ] Cache keys via URL versioning or
Vary
- [ ] Safe fallback (JPEG) on transform errors
- [ ] Image
alt
+ structured data for image SEO
Cache key details
- Suggested keys:
URL + Accept + DPR + Width + Quality
- Normalize
w
/q
in edge functions (e.g., 320/480/640/…) - Response headers example:
Cache-Control: public, max-age=604800, stale-while-revalidate=2592000
Vary: Accept, DPR
CDN-Cache-Status: HIT
AVIF/WebP fallback strategy
- Pick AVIF first by
Accept
, then WebP, fallback to JPEG - Server‑side fallback when timeouts/errors happen → JPEG
- Client
<picture>
withtype
helps browsers choose (usesrcset type
to make negotiation explicit)
<picture>
<source type="image/avif" srcset="hero.avif 1x, hero@2x.avif 2x" />
<source type="image/webp" srcset="hero.webp 1x, hero@2x.webp 2x" />
<img src="hero.jpg" alt="..." width="1200" height="630" />
</picture>
Normalizing on‑the‑fly resizing
- Fix width set: 320/480/640/768/960/1200/1600/2000, tied to
sizes
- Round incoming
w
to nearest to avoid cache fragmentation - Preset
q
per use: thumbnails 60/photos 70/UI 80
Security and abuse control
- Signed URLs to prevent unbounded transforms (
w
/h
/q
/fmt
signed) - Rate limit and circuit breaker on failures
- Disallow heavy filters that can DoS CPU
Observability / cost control
- Log: URL, fmt, w, q, dpr, cacheStatus, genTime, size
- Dashboards: format hit‑rates, median sizes, p95 gen times
- Cost: pre‑generate hot sizes; long TTL to reduce origin load
Edge function (pseudo)
export default async function handle(req) {
const u = new URL(req.url)
const w = normalizeWidth(u.searchParams.get('w'))
const q = normalizeQuality(u.searchParams.get('q'))
const fmt = negotiate(req.headers.get('Accept'))
const key = `${u.pathname}?w=${w}&q=${q}&fmt=${fmt}`
const cached = await caches.default.match(key)
if (cached) return cached
const out = await transform(u.pathname, { w, q, fmt })
return new Response(out.body, { headers: responseHeaders({ fmt, w, q }) })
}
Troubleshooting
- No image in legacy browsers → fix
Accept
negotiation or use<source type>
- Slow generation → reduce width set, preset quality, avoid double re‑encode
- Quality inconsistency → fix per‑use
q
; use moderate AVIFeffort
FAQ
Q. Should WebP/AVIF always be preferred?
A. Balance compatibility and generation cost. For brand‑critical surfaces, JPEG can still win.
Q. Won’t more Vary
axes reduce cache hit rates?
A. Normalize width/quality to control fragmentation. Limit DPR to where it matters.
Summary
“Correct cache keys” and “limited optimization for LCP candidates” is the shortest path to improving both perceived speed and search traffic. Start with hero images and A/B test small.