Skip to content

Conversation

@Macil
Copy link

@Macil Macil commented Dec 24, 2025

This PR replaces cache-busting query parameters on all file requests to allow browsers to cache files. With this PR, if you reopen a BlueMap page that you've opened in the same area before and the assets haven't changed, then barely any network traffic will happen (ie. <1 mb instead of 15+ mb for a short peek), even if you refresh or press the "update map" button.

The browser will automatically use any cached responses that are still fresh ("fresh" meaning that the cached response is younger than its Cache-Control header's max-age value), and will issue conditional requests for any stale cached assets if the web server delivered the assets with an ETag or Last-Modified header (as most setups with an external webserver will do, including the setups described by the External webservers and Cloudflare guides), saving bandwidth when nothing has changed by allowing the server to respond with an empty 304 response.

The "update map" button and requests made after a refresh now work by using Fetch's cache: "no-cache" option, which is superior to cache-busting because it allows the browser to make conditional requests if it has any (fresh or stale) cached responses.

If the web server (like BlueMap's built-in webserver) does not include ETag or Last-Modified headers in its responses, then Fetch with the cache: "no-cache" option works pretty similar to the current cache-busted queries.

There is one possible visible downside with this PR: on an initial non-refresh page load, the browser may use any fresh cached assets immediately without re-validating against the server, which is great for load times but may be bad if the assets were served with a large Cache-Control max-age value. BlueMap's built-in webserver sets the Cache-Control max-age to 24 hours, so someone re-opening a BlueMap within 24 hours may see assets that are up to 24 hours old (until they refresh or press the "update map" button). If this is an issue, I suggest changing BlueMap's built-in webserver to serve assets with a shorter max-age value, such as 1 hour or 10 minutes.

The one kind of hairy part of this PR is RevalidatingFileLoader.js, which is forked from Three.js's own FileLoader because it has multiple issues preventing it from being used here for this purpose (it doesn't support passing extra options to Fetch, and it can improperly de-dupe requests for the same URL made before and after pressing the "update map" button). The changes to it are pretty light and it seems to only use public APIs of Three.js, so I think it's a decent route. (I do also have an alternative hacky implementation of RevalidatingFileLoader at https://github.com/Macil/BlueMap/blob/betterCaching-monkeyPatch/common/webapp/src/js/util/RevalidatingFileLoader.js which is instead a wrapper around Three.js's FileLoader with some ugly monkey-patching. I don't trust this hacky route to be as future-proof.)

Removed cache-busting query parameters from all file requests to allow browsers to cache files properly.

The "update map" button revalidates all content but is now also able to make use of the browser cache, by using Fetch's `cache: "no-cache"` option which allows the browser to make a conditional request to check if the file has changed and then fall back to the cached version if it hasn't.
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

Successfully merging this pull request may close these issues.

1 participant