Resolved

S3 media files reload on every page refresh causing slow load times

Frontend
Performance
Caching
Service Worker
localStorage
AWS S3
JavaScript
Astro

AWS S3 media files and presigned URLs reload on each page refresh despite proper Cache-Control headers | Results in 6-10 second load times and 3-5MB bandwidth waste per refresh

An Astro-based frontend loading media from AWS S3 via presigned URLs suffered from redundant network requests, leading to slow page load times and high bandwidth usage.

Issue

The inspire gallery page experienced 6-10 second load times on every refresh due to:

  • Repeated API calls for presigned URLs for each media item.
  • 3-5MB of S3 media downloaded per page load (e.g., images and videos).
  • A Service Worker configured with a networkOnly strategy that bypassed caching, ignoring Cache-Control headers.

Culprit

The Service Worker was configured to bypass caching for all API requests, preventing the caching of presigned URL responses and S3 media files. This design forced fresh downloads on every page load, despite the presence of valid caching headers.

Solution

A three-layer caching system was implemented to address these issues:

1. Service Worker Cache Layer

Modified the Service Worker to introduce:

  • A 7-day cache for presigned URL API responses, aligning with AWS presigned URL time-to-live (TTL).
  • Indefinite caching for immutable S3 media files (e.g., images, videos).
  • Logic to detect and handle presigned URL API requests and S3 media files separately.

2. localStorage Fallback Layer

Added client-side caching in the Astro page component with:

  • A 7-day validation for cached URLs.
  • Automatic cleanup of expired or outdated cache entries.
  • Graceful fallback to API calls if both cache layers fail.

3. Performance Results

MetricBeforeAfter (Subsequent Visits)
Page Load Time6-10 seconds0.5-1 second (95% faster)
API Calls/Refresh20+ requests0 requests (100% reduction)
Data Transfer/Refresh3-5MB~50KB (99% reduction)
Cache Hit Rate0%>90%

The solution was verified using browser DevTools to confirm cached responses and implemented cache invalidation through version bumping to ensure updates.