Oliver White
1 May 2026 · 7 min read
Every artwork image on AI Art Arena is stored in Supabase Storage as the original upload — whatever format, whatever size the artist submitted. On the contest page, those images need to load fast. A 4MB PNG at full resolution would tank the LCP score and drive visitors away before the vote button renders.
When you use the next/image component with a remote image URL, Vercel intercepts the request, downloads the original from the source, transforms it to the optimal format and size, and caches the result at the edge. The browser receives a transformed image — not the original.
Original PNG
4.1MB
as uploaded
WebP (750px)
~180KB
after transformation
Size reduction
96%
same visual quality
Edge cache TTL
1 year
immutable after first hit
remotePatterns is a security allowlist — only images from approved hostnames are transformed. If you omit a hostname, next/image will return a 400 error instead of the image. This prevents your image optimization endpoint from being used as an open proxy to transform arbitrary external images.
| Attribute | What it does | CWV impact |
|---|---|---|
| fill | Image fills its container via position:absolute | CLS: none — container defines dimensions |
| priority | Adds <link rel=preload> to <head> for the image | LCP: significant — first images load earlier |
| sizes | Tells browser actual render size for srcset selection | Performance: browser picks correct size variant |
| aspectRatio wrapper | Reserves space before image loads | CLS: eliminated — no layout shift on load |
| minimumCacheTTL=31536000 | 1-year edge cache for transformed images | TTFB: near-zero on cache hit |
The combination of these attributes targets the three most impactful Core Web Vitals: LCP (Largest Contentful Paint) via preloading, CLS (Cumulative Layout Shift) via aspect-ratio containers, and FID (First Input Delay) via reduced JavaScript by keeping images in Server Components.
Built with this methodology
next/image is an image transformation pipeline, not just a component. Here is what actually happens when you configure remotePatterns, formats, and minimumCacheTTL — and how priority, sizes, and aspect-ratio wrappers affect LCP and CLS.
From the build log