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

Consider adding maxUnusedSeconds and updateStale to ExpirationPlugin config #3316

Open
atjn opened this issue Apr 25, 2024 · 0 comments
Open

Comments

@atjn
Copy link

atjn commented Apr 25, 2024

Hello new team :)

You closed #2863 because it was too old. I spent a lot of time researching and documenting this proposal, and I still think it is very relevant.

Library Affected:
workbox-expiration

Issue or Feature Request Description:
Hi there! Thanks for making this incredibly useful tool :)

I have a bunch of use cases where I need to either update a resource periodically or where I need to remove a resource that hasn't been used for a while. The ExpirationPlugin with maxAgeSeconds can sort of solve these use cases, but it isn't elegant and it has many bad edge cases.

I have tried to fix my use cases by making some custom plugins, but it is very complicated and requires a lot of IndexedDB calls. I then realised that 95% of the code I need has already been written for the maxAgeSeconds parameter, so maybe I should just propose some minor updates to workbox instead. And now that I have thought it through, I actually think this could solve a long list of challenges that would otherwise require custom code.

I will start with my proposed additions, then show an example. I am happy to discuss this in more detail, or provide more detailed use cases if you'd like :)

Proposed additions

The ExpirationPlugin gets two new parameters in its config:

maxUnusedSeconds number

This will be almost identical to maxAgeSeconds, but instead of calculating the time since the resource was last fetched, it calculates the time since the resource was last used on the website. In other words, how long ago was a request made for the cached resource.
As with maxAgeSeconds, if the resource hasn't been used for that amount of time, it is removed from the cache.

updateStale boolean

When a cached resource is older than maxAgeSeconds, it will normally be removed from the cache, but if updateStale is set to true, the plugin will instead try to refetch and update the cached resource. If the update fails, the old resource is kept.
This parameter does not affect removals caused by maxEntries or maxUnusedSeconds.

Example: A better image caching recipe

The default image caching recipe shows a simple "cache this for 30 days, then delete" use case.

Let's consider that plugin setup:

new ExpirationPlugin({
  maxEntries: 60,
  maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
}),

..vs a default plugin setup that leverages the proposed options:

new ExpirationPlugin({
  maxEntries: 60,
  maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
  updateStale: true,
  maxUnusedSeconds: 30 * 24 * 60 * 60, // 30 Days
})

Imagine that a user has been looking at an image every day for some time, but loses their internet connection 28 days after they saw the image for the first time, and the connection ends up being down for 7 days.

With the current setup, the image disappears 2 days after the internet goes down, and is missing for 5 days until the internet comes back up. There was no reason to delete the image, so this is not ideal.
With the proposed setup, there will be a failed attempt at updating the image after 2 days, but since it was very recently seen, it will be kept for 5 days until it can eventually be updated.

Now imagine that the image is completely static and never requires updates, and that the user has this app for 5 years.

With the current setup, the app must delete the image once every 30 days, so it will have to download identical copies of the image 120 times. It isn't possible to fix this, because we want the image to expire if it isn't used.
With the proposed setup, this would not be nearly as big a problem, because the image can be ETag validated, meaning it won't be downloaded again if the server copy hasn't changed.

With the proposed setup, it would also be possible to change the setup slightly so that no network activity occurs at all for all 5 years:

new ExpirationPlugin({
  maxEntries: 60,
  maxUnusedSeconds: 30 * 24 * 60 * 60, // 30 Days
})
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

1 participant