Application

Use the Application tool to manage storage for web app pages

- it's like being a digital hoarder, but organized!

We've got:

Service Workers:

They act as proxy servers between web applications, the browser, and the network. They primarily enable offline experiences, caching, push notifications, and background sync. Service workers intercept network requests, allowing control over how the application behaves in various situations, especially when the network is unavailable. They operate in a separate thread, without DOM access, and are designed to be fully asynchronous.

Background Workers (Web Workers):

They are general-purpose background threads designed to run CPU-intensive tasks without blocking the main thread, ensuring a responsive user interface. Background workers facilitate parallel processing, allowing complex computations or data processing to occur independently. They do not intercept network requests; instead, the main thread explicitly sends messages to them. Their lifespan is tied to the tab or page they are created in, terminating when the tab is closed.

Comparison:

Feature Service Worker Background Worker (Web Worker)
Purpose Network proxy, offline support, caching, push notifications Background processing, offloading CPU-intensive tasks
Network Intercepts network requests Does not intercept network requests
DOM Access No DOM access No DOM access
Lifespan Independent of the page/tab Tied to the page/tab
Use Cases PWAs, offline functionality, push notifications Complex calculations, data processing, real-time applications
Communication Intercepts fetch requests, listens for push events Receives messages via postMessage

Service Worker Example:


// In your main.js
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js')
    .then(registration => console.log('SW registered'))
    .catch(error => console.log('SW registration failed'));
}

// In sw.js
self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('v1').then(cache => {
      return cache.addAll([
        '/',
        '/styles.css',
        '/app.js'
      ]);
    })
  );
});

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => response || fetch(event.request))
  );
});
  
When does the install event fire?

The install event fires immediately after the service worker is successfully downloaded and parsed by the browser, triggered by the navigator.serviceWorker.register('/sw.js') call.

The sequence is:

  1. register() is called → browser downloads sw.js
  2. The SW is parsed successfully → install event fires
  3. event.waitUntil() keeps the SW in the "installing" phase until all cache.addAll() promises resolve
  4. If caching succeeds → SW moves to "waiting" (or "activated" if no previous SW exists)
  5. If caching fails (e.g., any resource in addAll 404s) → installation fails, SW is discarded

Key points:

When does the fetch event fire?

The fetch event fires on every network request made by pages the service worker controls — but with an important caveat:

Not immediately on first visit. Even though the SW installs and activates on the first visit, it does not control the page that registered it. The page must be navigated to again (refresh or revisit) for the SW to intercept its requests.

The timeline is:

  1. First visit → SW registers, installs, activates — but fetch does NOT fire. All requests go straight to the network.
  2. Second visit (or refresh) → the SW now controls the page → fetch fires for every request: the HTML page itself, CSS, JS, images, fonts, API calls — everything.

For each intercepted request, the code:

  1. Checks the cache for a match → if found, returns it (no network call)
  2. If not cached → falls back to a normal fetch() from the network

Exceptions — the fetch event does not fire for:

Web Worker Example:


// In your main.js
const worker = new Worker('worker.js');

worker.postMessage({ data: 'Start calculation' });

worker.onmessage = function(e) {
  console.log('Result:', e.data);
};

// In worker.js
self.onmessage = function(e) {
  // Heavy computation here
  const result = e.data.data + ' completed';
  self.postMessage(result);
};
  

While both operate in background threads, their roles are distinct. Service workers enhance web application capabilities related to network requests and offline access, whereas background workers improve performance by handling computationally intensive tasks separately from the main thread.

Typing cat gif