Understanding Caching Strategies
Caching is critical in PWAs to ensure fast load times and offline availability.
Different caching strategies can be used depending on the type of content being served.
1. Cache-First Strategy
The cache-first strategy serves resources from the cache first and only requests from the network if the cached version is unavailable. This is ideal for static assets such as JavaScript, CSS, and images.
Implementation Example
Modify service_worker.js to use cache-first for static assets:
self.addEventListener("fetch", (event) => {
if (event.request.url.includes("/assets/")) {
event.respondWith(
caches.match(event.request).then((cachedResponse) => {
return cachedResponse || fetch(event.request);
})
);
}
});
- If the requested asset is cached, it is served immediately.
- Otherwise, it is fetched from the network.
2. Network-First Strategy
The network-first strategy is best for frequently updated content, like API responses. It attempts to fetch fresh data first but falls back to the cache if offline.
Implementation Example
self.addEventListener("fetch", (event) => {
if (event.request.url.includes("/api/")) {
event.respondWith(
fetch(event.request)
.then((response) => {
return caches.open("dynamic-cache").then((cache) => {
cache.put(event.request, response.clone());
return response;
});
})
.catch(() => caches.match(event.request))
);
}
});
- The API request is attempted over the network first.
- If successful, the response is cached for future use.
- If offline, it serves the cached version if available.
3. Stale-While-Revalidate Strategy
This strategy serves content from the cache immediately while fetching an updated version from the network in the background. It ensures that users get instant responses while keeping content fresh.
Implementation Example
self.addEventListener("fetch", (event) => {
event.respondWith(
caches.open("stale-cache").then((cache) => {
return cache.match(event.request).then((cachedResponse) => {
const networkFetch = fetch(event.request).then((networkResponse) => {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
return cachedResponse || networkFetch;
});
})
);
});
- The cached version is served instantly if available.
- The request is still sent to the network in the background, updating the cache with the fresh response.