-
-
Notifications
You must be signed in to change notification settings - Fork 158
Description
Hey folks, I noticed earlier in my experimentation with maplibre and pmtiles that range requests against a .pmtiles file are not getting cached by browsers (I'm talking about Firefox and Chrome specifically).
I just ran across @bdon's https://bdon.github.io/overture-tiles/places.html#10.28/52.4901/13.3301 on mastodon and used this example to drill further down into what's happening because I can reproduce the issue there.
The summary is that currently neither Firefox nor Chrome can cache the range requests against .pmtiles, not even Chrome even tho it sends an If-Range with an ETag and the ETag matches (Firefox sends a regular Range request).
Firefox
Check this out. On second page load (warm cache)
- In red: the individual .mvt tiles are getting cached because these are individual files
- In blue: the range requests against the single .pmtiles are not getting cached and the requests always go through
Here are the request and response headers; notice
- Firefox sends a
Rangerequest - The .pmtiles have an ETag attached to it
Chrome
Check this out. On second page load (warm cache)
- In red: again the .mvt files are getting cached
- In blue: the range requests against the single .pmtiles are again not getting cached and requests always go through
Here are the request and response headers; notice
- Chrome sends an
If-Rangerequest and attached the ETag - The response returns the very same ETag, so even though the ETags are matching it's not getting cached
What's happening here?
I looked around it and it seems like both Firefox as well as Chrome's support for caching range requests is very limited.
For example for Firefox
- https://searchfox.org/mozilla-central/source/netwerk/protocol/http/nsHttpChannel.cpp#3617-3625
- https://searchfox.org/mozilla-central/source/netwerk/protocol/http/nsHttpChannel.cpp#3658-3662
they only allow to cache a range request for the very first byte range starting at byte zero.
// Don't cache byte range requests which are subranges, only cache 0-
// byte range requests.
if (IsSubRangeRequest(mRequestHead)) {
return NS_OK;
}How to move forward
With limited support of caching range requests in the browsers, I see the following ways forward
- We don't care about caching and always re-run requests against the .pmtiles file
- We have a lambda or similar in front of the static file turning range requests into individual file get requests
- We implement caching ourselves in the pmtiles lib here in this repo
- We implement caching ourselves e.g. as a maplibre plugin
I wanted to flag this with you since you might have thoughts on this and might have encountered this before.
What I wanted to add: pmtiles is such an amazing format for dropping a single file onto a static host that not having caching working by default is a bit unfortunate, because otherwise it shines and is such a cool idea 👌



