简体   繁体   中英

Avoid caching start_url with service worker

I'm having some problems on setting up a service worker for my website.

I only want to cache css/js/fonts and some images/svg, I don't want to cache the HTML since all of it is updated every minute.

It kinda works, but trying on my smartphone I keep getting the notification "Add to homescreen" even when I've already added it. And on the Chrome Dev app I don't get the Add button.

Also with the Lighthouse I get the following errors:

"Does not respond with a 200 when offline"

"User will not be prompted to Install the Web App, Failures: Manifest start_url is not cached by a Service Worker."

Right now my sw.js is like this. As you can see I commented the fetch part because it was caching the HTML and also the Cookies weren't working.

Is there around a simple Service Worker "template" to use?

const PRECACHE = 'app-name';
const RUNTIME = 'runtime';

// A list of local resources we always want to be cached.
const PRECACHE_URLS = [
'/css/file.css',
'/js/file.js',
'/images/logo.png',
'/fonts/roboto/Roboto-Regular.woff2'
]

// The install handler takes care of precaching the resources we always need.
self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(PRECACHE)
      .then(cache => cache.addAll(PRECACHE_URLS))
      .then(self.skipWaiting())
  );
});

// The activate handler takes care of cleaning up old caches.
self.addEventListener('activate', event => {
  const currentCaches = [PRECACHE, RUNTIME];
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));
    }).then(cachesToDelete => {
      return Promise.all(cachesToDelete.map(cacheToDelete => {
        return caches.delete(cacheToDelete);
      }));
    }).then(() => self.clients.claim())
  );
});

// The fetch handler serves responses for same-origin resources from a cache.
// If no response is found, it populates the runtime cache with the response
// from the network before returning it to the page.
self.addEventListener('fetch', event => {
  // Skip cross-origin requests, like those for Google Analytics.
  // if (event.request.url.startsWith(self.location.origin)) {
  //   event.respondWith(
  //     caches.match(event.request).then(cachedResponse => {
  //       if (cachedResponse) {
  //         return cachedResponse;
  //       }

  //       return caches.open(RUNTIME).then(cache => {
  //         return fetch(event.request).then(response => {
  //           // Put a copy of the response in the runtime cache.
  //           return cache.put(event.request, response.clone()).then(() => {
  //             return response;
  //           });
  //         });
  //       });
  //     })
  //   );
  // }
});    

I'm not sure why the install banner appears but the two errors given by lighthouse are related to the missing caching of the very start_url, propably index.html. So Lighthouse will always be telling you about those if you follow the caching strategy you described here.

I suggest you could try Workbox and their runtime caching. Runtime caching, in a nutshell, works like so: you specify urls like *.svg, *.css etc. and the SW caches them once the client first asks them. In the future, when the files are already cached, the SW serves them from the cache to the client. Basically you tell the SW to cache this and that kind of urls when it encounters them and not in advance.

Runtime caching could very well be accompanied by precaching (that may also be found from Workbox!) to cache a bunch of files.

Check it out here: https://workboxjs.org

They have a couple of examples and plugins for build tooling.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM