5

I am trying to implement offline capabilities for my web app but I'm experiencing some strange behavior while offline and it's probably something I'm missing since it's reproducible both in Chrome and Firefox.

I'll describe below what the sample app I created does:

Steps to reproduce

  1. Open a new Chrome tab and open console view.
  2. Navigate to sample app (hosted on Netlify).
  3. Observe log messages confirming the installation and activation of service worker, plus the creation and population of the app's cache storage.
  4. Go to application tab in developer tools and confirm that cache was created and populated
  5. Under "Service Worker" enable "Offline" to make network unavailable.
    • Alternatively just turn off your wifi/network.
  6. Refresh page.

Observed behavior

  • The cache storage MyCache previously created by the service worker disappears.

Expected behavior

  • The page fails to load as expected but the cache storage should remain available after refreshing so that the app can use it for serving content while being offline.

HTML code

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>Vanishing cache storage test</title>
    <script>
        if ('serviceWorker' in navigator) {
            window.addEventListener('load', () => {
                navigator.serviceWorker.register('/sw.js')
                    .then((registration) => {
                        console.log('Service worker registered sucessfully:', registration);
                    })
                    .catch((error) => {
                        console.error('Failed to register service worker:', error.stack);
                    });
            });
        }
  </script>
</head>
<body>
  <h1>Hi!</h1>
</body>
</html>

Service worker

const CACHE_NAME = 'MyCache';

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then((cache) => {
        return cache.add('/');
      })
      .then(() => {
        console.debug(CACHE_NAME, 'created and populated');
      })
  );
});

self.addEventListener('activate', (event) => {
  console.debug('SW activated');
});

OS + browser version

Google Chrome Version: 87.0.4280.141 (Official Build) (x86_64) Firefox version: 85.0b5 (64-bit, Developer Edition) OS: macOS v11.1 (Big Sur)

Question

Is this expected behavior? If so, why?

Notes

  • I couldn't test on Safari because I there's no visible way to visualize cache storage content (ugh!).
  • After refreshing on Firefox, you might need to close and reopen devtools to have the Storage tab refresh itself.

before going offline: cache is A-OK after refreshing while offline: cache is gone!

martinzen
  • 83
  • 2
  • 5

2 Answers2

5

The cache content is still there. If you go online and refresh the page, you can see it again (it isn't being redownloaded).

I've filed https://bugs.chromium.org/p/chromium/issues/detail?id=1164309, as storage should be visible in devtools even if the page doesn't load.

JaffaTheCake
  • 13,895
  • 4
  • 51
  • 54
1

No, cache storage does not get disappears after going offline. The reason you are experiencing this behavior is because your site is not working in offline mode right now.

Add below fetch event handler in your service worker and your site will work fine in offline mode as well.

self.addEventListener("fetch", function (event) {
  event.respondWith(
    caches.match(event.request).then(function (response) {
      if (response) {
        return response;
      }
      return fetch(event.request);
    })
  );
});
Vimal Patel
  • 2,785
  • 2
  • 24
  • 38
  • You are actually right, adding a fetch handler makes the bug go away for some reason. Thanks. – martinzen Jan 08 '21 at 21:12
  • 1
    SW works as proxy between browser and server request. When you add a fetch event handler your resource are served from cached if it is available. As you are already caching your index page your application will work, if you dont have anything in cache, then it will not work. If this solve your problem, please mark the answer as accepted. – Vimal Patel Jan 09 '21 at 04:25
  • I suppose `event.respondWith()` should be called one time at least. I had `onFetch` listener with wrong condition and `respondWith` function was never called, so I had the same error - cache was unavailable in offline mode. – Alex Gusev Mar 28 '22 at 15:06