Skip to content

Range requests browser caching not working in Firefox (browser bug) #272

@daniel-j-h

Description

@daniel-j-h

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)

  1. In red: the individual .mvt tiles are getting cached because these are individual files
  2. In blue: the range requests against the single .pmtiles are not getting cached and the requests always go through

firefox-cache-1

Here are the request and response headers; notice

  1. Firefox sends a Range request
  2. The .pmtiles have an ETag attached to it

firefox-cache-2

Chrome

Check this out. On second page load (warm cache)

  1. In red: again the .mvt files are getting cached
  2. In blue: the range requests against the single .pmtiles are again not getting cached and requests always go through

chromium-cache-1

Here are the request and response headers; notice

  1. Chrome sends an If-Range request and attached the ETag
  2. The response returns the very same ETag, so even though the ETags are matching it's not getting cached

chromium-cache-2


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

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

  1. We don't care about caching and always re-run requests against the .pmtiles file
  2. We have a lambda or similar in front of the static file turning range requests into individual file get requests
  3. We implement caching ourselves in the pmtiles lib here in this repo
  4. 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 👌

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions