From Slow to Instant: How I Made Bokkah.com Insanely Fast by Caching Images with a Service Worker
Posted by Nuno Marques on 2 Feb 2025
What if I told you that you could make your React app load images almost instantly with a single technique?
This isn't some theoretical trick—it’s exactly what I achieved on Bokkah.com.
The results?
✅ Hundreds of images loaded in milliseconds
✅ Significantly fewer network requests
✅ A near-instant browsing experience
But here’s the kicker: This optimization isn't just about images.
It can extend to API calls, AI-generated content, and dynamic collections, making your entire app feel blazing fast.
Let’s deep dive into the power of service workers and how they transformed my app.
The Problem: Why Image Loading Is a Performance Killer
1. Every Image Request Adds Latency
Each time your app fetches an image from the server or a CDN, there's an inherent delay due to:
- DNS lookup
- TLS handshake
- Server processing
- Network round trip time
- Image decoding
Even with an optimized CDN, these requests stack up, affecting performance.
2. Unnecessary Network Calls on Revisits
Browsers already cache assets, but:
- The default cache policy is not aggressive enough.
- If the cache is invalidated, the browser still re-fetches the image.
- Users on slow networks or with limited bandwidth experience significant delays.
3. Core Web Vitals and User Perception
Slow-loading images hurt:
- LCP (Largest Contentful Paint) → SEO impact
- FCP (First Contentful Paint) → User perception
- TBT (Total Blocking Time) → Interaction readiness
Even with lazy loading, these performance hits add up.
So, what’s the fix?
👉 A Service Worker caching all images!
The Solution: Service Worker + Image Caching
Instead of relying on default browser caching, I implemented a custom caching strategy using a Service Worker.
How It Works:
- Intercept every image request
- Check if the image is already cached
- If cached → Load instantly from storage
- If not cached → Fetch, store it, and serve
Here’s the Service Worker Code That Made It Happen
To implement this optimization, I added the following service worker inside my React app’s frontend/public/service-worker.js
file:
self.addEventListener('fetch', (event) => {
if (event.request.destination === 'image') { // Cache only images
event.respondWith(
caches.open('image-cache').then((cache) =>
cache.match(event.request).then((cachedResponse) => {
return cachedResponse || fetch(event.request).then((networkResponse) => {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
})
)
);
}
});
Implementing It in React
Once the Service Worker was created, I registered it in my index.tsx
:
// Register the service worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker
.register('/service-worker.js') // This file should be inside the `public/` folder
.then((registration) => {
console.log('Service Worker registered with scope:', registration.scope);
})
.catch((error) => {
console.error('Service Worker registration failed:', error);
});
});
}
Why This Is a Game-Changer for Performance
The Before and After Results:
✅ Before → Each image was fetched from the network every time
✅ After → Cached images load instantly with zero network latency
Here’s what happened in the network tab after implementing this:
- Hundreds of images loaded in under 30ms
- (ServiceWorker) served images from cache instead of the network
- Reduced total network requests, making my Bokkah App feel near-instant
Extending This Technique Beyond Images
While caching images dramatically improves load times, this technique isn’t limited to static assets. If your app relies on AI-generated content, dynamic collections, and frequent API calls, these too can benefit from caching strategies.
By extending service worker caching to API responses and AI-generated content, you can:
✅ Reduce redundant OpenAI API calls → Faster content generation & lower costs
✅ Cache user collections & data → Instant access without reloading
✅ Optimize dynamic content → Minimize unnecessary database queries
This approach transforms not just images, but your entire app into a faster, more efficient experience.
Further Reading and References
To deepen your understanding of service workers and caching strategies, check out these resources:
- Service Workers: An Introduction
A beginner-friendly guide explaining service workers and their capabilities. - Measuring the Real-world Performance Impact of Service Workers
A case study on how service workers improve web performance. - Progressive Web Apps (PWAs) and Caching Strategies
Explains how caching in service workers helps PWAs work offline. - Workbox: Google's Library for Advanced Caching
If you want to go beyond manual caching, Google's Workbox simplifies service worker management.
Final Thoughts: Why You Should Implement This ASAP
With just a few lines of JavaScript, I made my React app insanely fast.
The Service Worker strategy:
✅ Reduced image load times from seconds to milliseconds
✅ Cut down network requests significantly
✅ Created a near-instant browsing experience
But this is just the beginning.
If you're building a web app with dynamic content, AI-powered features, or social sharing, caching isn't optional—it's a must.
Key Takeaways:
- Use service workers to cache images for instant load times.
- Expand caching to API responses to reduce costs & latency.
- Make AI-generated recipes & collections available offline.
- Improve Core Web Vitals (LCP, FCP, TBT) for better SEO.
Have you tried using service workers in your app?