Image Performance Before and After Adding CloudFront
Tracing an S3 image request through the browser, Next.js image optimization, and CloudFront caching.
- Next.js
- AWS
- CloudFront
- Web Optimization
Summary
Our team introduced AWS CloudFront to improve product-image delivery in Snack, a Next.js application deployed on Vercel.
The /products page loads many images stored in Amazon S3, making it an ideal page for comparing performance before and after implementing CloudFront.
I tested both versions in production using Lighthouse’s mobile and desktop presets. The results showed faster Speed Index scores and higher overall performance scores, although LCP did not improve consistently.
One limitation: Vercel’s Next.js Image Optimization has its own image cache. Later Lighthouse runs may load images from Vercel without reaching CloudFront. Because of this, the results show how the full production setup performed after adding CloudFront, rather than what CloudFront improved on its own.
Implementation Result
| Metric | Before | After | Change |
|---|---|---|---|
| Mobile LCP | 7.5s | 7.7s | +0.2s |
| Mobile CLS | 0 | 0 | — |
| Mobile Speed Index | 2.4s | 1.7s | −0.7s |
| Mobile Performance | 71 | 75 | +4 |
| Desktop LCP | 1.8s | 1.6s | −0.2s |
| Desktop CLS | 0 | 0 | — |
| Desktop Speed Index | 1.2s | 0.5s | −0.7s |
| Desktop Performance | 92 | 95 | +3 |
View test method
- Environment: Production
/productspage deployed on Vercel. - Comparison: Product image sources changed from direct S3 URLs to CloudFront URLs.
- Browser: Chrome Incognito with browser caching disabled in DevTools.
- Mobile: Lighthouse mobile preset with its default simulated Slow 4G network and CPU throttling.
- Desktop: Lighthouse desktop preset with its default throttling settings.
- Controlled variables: The same page, images, production environment, and Lighthouse settings were used for both versions.
- Runs: Five runs for each mobile and desktop test, with the median reported above.
- Scope: The complete production pipeline, including Vercel’s Next.js Image Optimization cache, was measured rather than CloudFront alone.
Result Analysis
The clearest improvement was in Speed Index. Mobile Speed Index improved by 0.7 seconds, while desktop Speed Index also improved by 0.7 seconds. The overall performance score increased by four points on mobile and three points on desktop.
LCP did not improve consistently. Desktop LCP improved by 0.2 seconds, while mobile LCP became 0.2 seconds slower. This suggests that the updated pipeline helped display page content sooner overall but did not resolve the mobile LCP bottleneck. I plan to investigate that issue separately.
How the Image Request Flows
Vercel first checks its optimized-image cache and only contacts CloudFront when it needs the source image. CloudFront then checks its cache hierarchy before contacting S3.
Browser
Checks its own cache first
Vercel / Next.js Image Optimization
Checks its optimized-image cache, then requests the source when needed
CloudFront
Checks its edge and regional caches for the source image
S3 (Oregon)
Origin, only reached on a full miss
Limits
- CloudFront was not measured in isolation. Vercel’s Next.js Image Optimization also caches optimized images. After the first request, later Lighthouse runs may receive a Vercel cache hit without contacting CloudFront. The request-flow diagram shows where a Vercel hit stops the request.
- CloudFront does not fix late LCP discovery. It can reduce the time needed to retrieve an image after it is requested, but it cannot make the browser discover the LCP image earlier. I plan to investigate that issue separately.
- Lighthouse results naturally vary. Network conditions, service load, and background activity can affect individual runs even with simulated throttling. Reporting the median of five runs reduces the effect of outliers but does not remove all variation.