Blog>
Snippets

Smart Cache Updating and Invalidating

Showcase a strategy to selectively update and invalidate caches when new content is available or certain conditions are met.
const cacheName = 'my-app-cache-v1';
const contentToCache = ['/index.html', '/styles/main.css', '/scripts/main.js'];

// Function to install the cache
async function installCache(e) {
  const cache = await caches.open(cacheName);
  return cache.addAll(contentToCache);
}

// Listen to the install event
self.addEventListener('install', (e) => {
  e.waitUntil(installCache(e));
});
This code creates a cache upon service worker installation event with predefined assets to be cached. It defines a cache name and an array of content paths to be cached initially. Then, it adds an event listener for the 'install' event to install the cache and the assets.
// Function to update cache
async function updateCache() {
  const cache = await caches.open(cacheName);
  const requests = await cache.keys();
  await Promise.all(requests.map(async (request) => {
    const response = await fetch(request);
    if (response) {
      return cache.put(request, response);
    }
  }));
}

// Manual invocation to update cache
updateCache();
This function, when called, updates all cached content by fetching the latest version and re-caching it. It opens the cache, retrieves all cached requests, and then fetches the latest version for each request. If a new response is received, it updates the cache with the new response.
// Function to remove old caches
function invalidateCaches() {
  caches.keys().then((cacheNames) => {
    return Promise.all(
      cacheNames.map((cacheName) => {
        if (cacheName !== 'my-app-cache-v1') {
          return caches.delete(cacheName);
        }
      })
    );
  });
}
This function removes any caches that do not match the current cache name. It first retrieves all cache names and then deletes any caches that are out-of-date, ensuring only the relevant cache remains active.
// Service worker fetch event with cache-first strategy updated with smart invalidation
self.addEventListener('fetch', (e) => {
  e.respondWith(
    caches.match(e.request).then((response) => {
      // Return the cached response if present
      return response || fetch(e.request).then((fetchResponse) => {
        return caches.open(cacheName).then((cache) => {
          // Update the cache with the new fetched response and return it
          cache.put(e.request, fetchResponse.clone());
          return fetchResponse;
        });
      }).catch(() => {
        // Fallback content or response in case of network failure
      });
    })
  );
});
This code snippet demonstrates a Smart Cache strategy using a service worker. It first tries to fetch content from the cache (cache-first strategy). If the cached content is not found, it fetches from the network, updates the cache with the fresh response, and then returns that response. This maintains updated content in the cache while providing a quick response to the user.