AdamBien / effectiveweb.training

Repository for Effective Web Online Course / airhacks.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Service Worker not caching as expected?

hrstoyanov opened this issue · comments

@AdamBien
Thanks for the great course!

One issue I encountered was that loading assets upon install event did not work for me - it is very weird, the cache did get populated (as seen in the Chrome cache inspector tab), but subsequent service worker fetch events found nothing in the cache and ended up downloading assets over the network. Except for a style.css, which is the only thing found in the cache! ...Spent a whole day hacking it, got nowhere! This might be an issue with the latest Chrome (Version 86.0.4240.80), especially if you did not see anything like this in 2019, when you recorded the course.

Here is the install event code that did not work for me:

const cacheName = 'stockz-cache-v20';

const resources = [
    './index.html',
    './style.css',
    './app.js',
     './AirNav.js',
     './AirSlot.js',
     './AirCrumb.js',
     './AirUpdate.js',
     './views/TotalView.js',
     './views/AirElement.js',
     './views/AddView.js',
     './views/ListView.js',
     './views/OverView.js',
     './views/AboutView.js',
     './views/Stocks.js',
     './web_modules/d3.js',
     './web_modules/lit-html.js'
];


const prefetch = (name) => caches.open(name).then(cache => cache.addAll(resources));

//Install - the cache does get populated as seen in the Chrome inspector console, but subsequent fetch events cannot find items in //the cache!
self.addEventListener('install', e => {
    //console.log("worker install - prefetch")
    self.skipWaiting();
    e.waitUntil(prefetch(cacheName));
});

What works though, is lazily populating the cache after fetch fails to find the asset in the cache

self.addEventListener('fetch', event => {
    const {request} = event;
    event.respondWith(caches
            .match(request)
            .then(response => {
                if (response) {
                    //console.log(`worker fetch from cache ${request.url}`);
                    return response;
                }
                //console.log(`worker fetch missed in cache ${request.url}`);
                return fetch(event.request).then(
                    response => {
                        //     -Ensure the response is valid.
                        //     -Check the status is 200 on the response.
                        //     -Make sure the response type is basic, which indicates that it's a request from our origin. This means that requests to third party assets aren't cached as well.
                        if (!response || response.status !== 200 || response.type !== 'basic') {
                            return response;
                        }

                        // IMPORTANT: Clone the response. A response is a stream
                        // and because we want the browser to consume the response
                        // as well as the cache consuming the response, we need
                        // to clone it so we have two streams.
                        const responseToCache = response.clone();

                        caches.open(cacheName)
                            .then(cache => {
                                cache.put(event.request, responseToCache);
                                //console.log(`added to cache ${request.url}`);
                            });

                        return response;
                    }
                );
            })
    );
});

I wonder if you have time to re-test this?