# Question 68

### Question

Can you explain how to use service workers to cache assets and improve performance?

### Answer

Service workers are a powerful tool for building offline-first web applications and improving website performance.

Here's a breakdown of how to use them for caching assets:

**1. Registering a Service Worker:**

```javascript
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js')
      .then(registration => console.log('Service worker registered:', registration))
      .catch(error => console.log('Service worker registration failed:', error));
  });
}
```

* Include `service-worker.js` in your HTML file, and this script will register the service worker when the page loads.

**2. The Service Worker (`service-worker.js`):**

```javascript
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open('my-cache') 
      .then(cache => cache.addAll([
        '/', 
        '/index.html', 
        '/style.css', 
        '/script.js', 
        '/images/logo.png' 
      ]))
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
        if (response) {
          return response; // Return cached response
        } else {
          // Fetch from network if not in cache
          return fetch(event.request)
            .then(res => {
              // Clone and cache the fetched response
              const clonedResponse = res.clone();
              caches.open('my-cache').then(cache => cache.put(event.request, clonedResponse));
              return res; 
            });
        }
      })
  );
});
```

* **`install` Event:** This event fires when the service worker is first installed. Inside it, we use `caches.open()` to open a cache named "my-cache" and add all the listed assets to it using `cache.addAll()`.
* **`fetch` Event:** This event handles all network requests made by the web page.
  * We check if the requested resource is in the cache using `caches.match(event.request)`. If found, we return the cached response immediately.
  * If not found, we fetch the resource from the network and:
    * Clone the fetched response to keep the original intact for the page.
    * Store the cloned response in the cache for future requests.
    * Return the original fetched response to the page.

**Key Points:**

* **Caching Strategy:** Choose a caching strategy that suits your needs. You can use various techniques like:
  * **Cache First:** Serve from cache, fetch if not available.
  * **Network First:** Fetch from network, cache if successful.
* **Expiration:** Use expiration headers or TTL (Time To Live) to control how long cached assets are valid.
