Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a Custom Pre-Caching strategy Plugin #1956

Closed
wallsmetalroofing opened this issue Mar 14, 2019 · 6 comments
Closed

Create a Custom Pre-Caching strategy Plugin #1956

wallsmetalroofing opened this issue Mar 14, 2019 · 6 comments

Comments

@wallsmetalroofing
Copy link

Question?/Plugin Help
I was typing up the question on StackOverFlow and quickly realized that it would be to broad to ask there, so I decided to ask here. What workbox caching strategy should I use for these custom rules?

I want to precache and/or update files based on their revision string, if they are already loaded once. If not then ignore them. Also I'd like to expire files based on the last time used rather then how old they are.

I found this plugin example to try and use it as a template when creating a new plugin but I still couldn't make heads or tails of it. https://gist.github.com/prateekbh/7f047938b5d1aab1b8a8b0f92d093ef2

To figure out when to cache the file I was thinking of storing a additional time value in the precaching index db whenever the file gets accessed. When the precache function would run because of a revision change I would then use that value to decide if I want to precache the file again or simply drop it. Once a file gets dropped it wouldn't be in the index db anymore so it wouldn't get loaded even if its in the precache list. Only when the user accesses that file again would I want to load it and save into the database.

Does anyone know of a plugin that does something similar that I could modify? Service workers are still a little over my head so I'm struggling to write my own atm.

@jeffposnick
Copy link
Contributor

What your describing sounds roughly like the ideas in #155

If you agree with that assessment, I'd like to close this issue in favor of using that to track this request.

As you might be able to infer from the ~2 years that have passed since that issue was opened, implementing this sort of functionality this is not a trivial task given the way our precaching implementation, and the service worker lifecycle, are designed. But it's still something that we'd like to solve as best we can in a future release.

@wallsmetalroofing
Copy link
Author

I think I just figured out a way that seems to work. Thanks.

setup gets the list of files from index db

const precacheController = new workbox.precaching.PrecacheController();

// silence a eventListener warning
workbox.precaching.addRoute( [] );

const setup = new Promise( async ( resolve, reject ) => {
    // create a list to use to set precaching options
    let list = await precache.create();
    console.log( "Pre Cache List", list );

    workbox.precaching.addRoute( list.route, precacheOptions );
    // add a list of files to precache
    precacheController.addToCacheList( list.precache, precacheOptions );

    resolve();
} );

Then on install wait for the setup to finish and then run the precacheController.install()

self.addEventListener("install", ( event ) => {

    const install = async () => {

        try {
            await setup;
        } catch ( err ) {
            console.error( err );
        }

        // install the precache controller
        await precacheController.install();

        self.skipWaiting();
    };


    event.waitUntil( install() );

});

@jeffposnick
Copy link
Contributor

jeffposnick commented Mar 15, 2019

setup gets the list of files from index db

I think you're going to run into problems after you've got some clients with a current version of your service worker, and then you deploy some updates. Changing the values stored in IndexedDB won't trigger a service worker update, and workbox-precaching really relies on updates happening in order to ensure that the files that are precached are kept up to date.

I'd instead encourage you to consider using runtime caching, perhaps using this recipe for passing along a list of URLs that should "prime" the runtime cache, instead of precaching for this approach.

@philipwalton
Copy link
Member

BTW, the example @jeffposnick linked to uses the Resource Timing API. If one of your goals is to only cache resources that are already in the HTTP cache, you can determine that by checking the transferSize property of the resource entry. If the transfer size is 0, it means it's most likely already cached.

@wallsmetalroofing
Copy link
Author

@jeffposnick Is that still relevant if I use this example https://developers.google.com/web/tools/workbox/modules/workbox-precaching#using_precachecontroller_directly and create a list of files in the main service worker file with their revision value in a list and then use the indexdb that I setup to boot out the files that I don't need cached? Or would I still run into problems. I don't see how it would as the service worker would get updated everytime I actually made a change to any file. And correct me if I'm wrong, but if I only boot out using the index db and not actually add anything from index db it should also be able to remove old files.

@jeffposnick
Copy link
Contributor

If you include revision info inline in your top-level service worker and just use IndexedDB as a white/blacklist to determine which URLs actually get cached, then that would address my concerns about updates and the service worker lifecycle. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants