plentico / plenti

Static Site Generator with Go backend and Svelte frontend
https://plenti.co
Apache License 2.0
985 stars 50 forks source link

Use query params to bust cache #315

Closed jimafisk closed 2 months ago

jimafisk commented 2 months ago

We introduced the "fingerprint" feature and configurable JS entrypoint in v0.6.29 (see https://github.com/plentico/plenti/issues/295) to automatically break the cache for clientside JS when changes are made and a new build is run.

The general consensus of many folks was it's better to modify the actual filename than set a query parameter so we essentially took that route (actually modifying the folder name that holds all our clientside JS and JSON content): https://stackoverflow.com/questions/9692665/cache-busting-via-params

However, Chrome version 110 release a new memory saver feature that's enabled by default: https://news.ycombinator.com/item?id=34886382. This is a memory saving technique that per this ars tech article works like this:

"When a tab is discarded, its title and favicon still appear in the tab strip but the page itself is gone, exactly as if the tab had been closed normally. If the user revisits that tab, the page will be reloaded automatically."

The obvious problem here is if you had a tab that was initially loaded with this entrypoint:

<script type="module" src="/anpgjvNtUD/core/main.js"></script>

Then you let it become inactive, and some changes were pushed in the meantime, the entrypoint would change, and could look like:

<script type="module" src="/woeltiZIDv/core/main.js"></script>

When you revisit your inactive tab, it will still have reference to the initial fingerprint (anpgjvNtUD) and try to refetch those assets, however they are no longer there, they are instead located under the new fingerprint (woeltiZIDv). This will break your clientside JS and CSS and the site will look broken until you refresh and the HTML document gets reference to the new path.

There are lots of other valid criticisms of this new feature (ever have mobile users double submit a form or payment simply by re-opening an old browser tab on their phone?), so it's possible chrome will disable this by default in the future, but we can't wait around hoping that's going to happen because in the meantime people won't understand and will assume the problem in with the website, and not an ill-thoughtout feature of their browser. I think using query params to break the cache instead could get around this, because at least the file will still be located at a consistent filepath.

jimafisk commented 2 months ago

This should be available in v0.6.38.

You can now access a magic prop env.fingerprint without adjusting config or passing any flags (it's always available). You would simply add this to your <head> as a query string like:

<script type="module" src="/spa/core/main.js?{env.fingerprint}"></script>
<link rel='stylesheet' href="/spa/bundle.css?{env.fingerprint}">

You can still set a custom /spa folder via "entrypoint_js" in plenti.json and access it in your app from env.entrypointJS. If you set this to :fingerprint it will get set to the same env.fingerprint value for the build, however, doing that instead of using a query string like mentioned above it could result in the inactive tab issue that this ticket was created to fix.