Day 4: Caching Strategies with Service Workers


Today, you’ll implement different caching strategies with your service worker to optimize the performance and offline capabilities of your Progressive Web App (PWA). Caching strategies define how resources are stored and retrieved, enabling faster load times and offline support.

What You Will Do Today:

  1. Understand caching strategies in service workers.
  2. Implement different caching strategies (Cache-First, Network-First, Stale-While-Revalidate).
  3. Test caching behavior for online and offline scenarios.

Step 1: Understanding Caching Strategies

There are several caching strategies commonly used in PWAs:

  1. Cache-First: The service worker checks the cache for resources first. If found, it serves the cached version; otherwise, it fetches from the network.
  2. Network-First: The service worker tries the network first. If the network request fails, it falls back to the cache.
  3. Stale-While-Revalidate: The service worker serves the cached resource and simultaneously fetches an updated version from the network to update the cache.

Step 2: Setting Up Cache-First Strategy

Let’s start by implementing a Cache-First strategy for static assets like CSS and JavaScript files. This is useful because these assets don’t change frequently.

  1. Open public/service-worker.js and update the fetch event listener to apply the Cache-First strategy for static assets.
   const CACHE_NAME = 'my-pwa-static-cache-v1';
   const STATIC_ASSETS = [
     '/',
     '/index.html',
     '/static/js/bundle.js',
     '/static/css/main.css'
   ];

   self.addEventListener('install', (event) => {
     event.waitUntil(
       caches.open(CACHE_NAME).then((cache) => {
         console.log('Opened static cache');
         return cache.addAll(STATIC_ASSETS);
       })
     );
   });

   self.addEventListener('fetch', (event) => {
     if (STATIC_ASSETS.includes(new URL(event.request.url).pathname)) {
       event.respondWith(
         caches.match(event.request).then((response) => {
           return response || fetch(event.request).then((response) => {
             return caches.open(CACHE_NAME).then((cache) => {
               cache.put(event.request, response.clone());
               return response;
             });
           });
         })
       );
     }
   });

Step 3: Implementing Network-First Strategy for Dynamic Content

Dynamic content (such as API responses) benefits from a Network-First strategy to ensure users see the latest data. This strategy fetches from the network first, caching the response and only serving from the cache if the network request fails.

  1. Update the fetch event listener to add a Network-First strategy for requests to /api/:
   const DYNAMIC_CACHE_NAME = 'my-pwa-dynamic-cache-v1';

   self.addEventListener('fetch', (event) => {
     const requestUrl = new URL(event.request.url);

     // Network-First for API requests
     if (requestUrl.pathname.startsWith('/api/')) {
       event.respondWith(
         fetch(event.request)
           .then((response) => {
             return caches.open(DYNAMIC_CACHE_NAME).then((cache) => {
               cache.put(event.request, response.clone());
               return response;
             });
           })
           .catch(() => caches.match(event.request))
       );
     }
   });

Step 4: Implementing Stale-While-Revalidate Strategy

For frequently updated resources like the homepage, you can use the Stale-While-Revalidate strategy. This serves the cached version immediately while updating it in the background.

  1. Update the fetch event listener to add a Stale-While-Revalidate strategy:
   self.addEventListener('fetch', (event) => {
     const requestUrl = new URL(event.request.url);

     // Stale-While-Revalidate for the homepage
     if (requestUrl.pathname === '/') {
       event.respondWith(
         caches.match(event.request).then((cachedResponse) => {
           const fetchPromise = fetch(event.request).then((networkResponse) => {
             caches.open(CACHE_NAME).then((cache) => {
               cache.put(event.request, networkResponse.clone());
             });
             return networkResponse;
           });
           return cachedResponse || fetchPromise;
         })
       );
     }
   });

Step 5: Testing Caching Strategies

  1. Open your app in Google Chrome and go to Developer Tools (F12 or right-click and select “Inspect”).
  2. Navigate to the Application tab, then to Cache Storage and Service Workers.
  3. Switch to Network > Offline to simulate offline mode and observe how different assets load based on the caching strategies.
  • Static Assets: Should load from the cache due to the Cache-First strategy.
  • API Data: Should load the latest version if online, or from the cache if offline.
  • Homepage: Should load from the cache immediately and revalidate in the background.
See also  Day 5: Implementing Authentication with JWT in React Native

Summary

Today, you implemented caching strategies with a service worker to control how different resources are cached and served. This allows your app to load quickly and function offline with up-to-date data.

Tomorrow, you’ll learn about IndexedDB for local data storage in your PWA.


Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.