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

Prefetch not working in Firefox #12337

Closed
1 task done
JusticeMatthew opened this issue Oct 29, 2024 · 9 comments
Closed
1 task done

Prefetch not working in Firefox #12337

JusticeMatthew opened this issue Oct 29, 2024 · 9 comments
Labels
needs triage Issue needs to be triaged

Comments

@JusticeMatthew
Copy link

Astro Info

Astro                    v4.16.7
Node                     v18.20.3
System                   Linux (x64)
Package Manager          npm
Output                   static
Adapter                  none
Integrations             none

If this issue only occurs in one browser, which browser is a problem?

Firefox

Describe the Bug

Prefetches appear to not be happening in Firefox. This was first brought to my attention by discord member Matthias at which time I noticed it happening in my own deployed project

If you go to the minimal repro, open the preview in a new tab, and check the dev tools you will see under the network tab the prefetchs are successfully made in chrome but are nowhere to be found in firefox (despite the console saying it prefetched them) when hovering over the links.

What's the expected result?

I expect to see the fetch request happen in Firefox as you do in chrome. With the current behavior it appears the prefetch may not be happening at all

Link to Minimal Reproducible Example

https://stackblitz.com/edit/withastro-astro-q6tjrk?file=src%2Fpages%2Findex.astro

Participation

  • I am willing to submit a pull request for this issue.
@github-actions github-actions bot added the needs triage Issue needs to be triaged label Oct 29, 2024
@siwalikm
Copy link

cannot reproduce this, I'm on a Mac M1

ff-astro.mov

@JusticeMatthew
Copy link
Author

JusticeMatthew commented Oct 29, 2024

Fascinating.... I'm not sure what the difference is then, perhaps it's windows related?

Recording.2024-10-29.180021.webm

@JusticeMatthew
Copy link
Author

Apparently my prefetch was disabled in firefox

closing this as it's not an astro issue clearly, though still don't know why the get requests are failing on my production site

@bluwy
Copy link
Member

bluwy commented Oct 30, 2024

Might worth checking if it's related to https://docs.astro.build/en/guides/prefetch/#firefox. Also make sure there's no ad-blockers disabling prefetching too.

@JusticeMatthew
Copy link
Author

Might worth checking if it's related to https://docs.astro.build/en/guides/prefetch/#firefox. Also make sure there's no ad-blockers disabling prefetching too.

It was exactly related to that! Lukas in the discord linked me the original issue where you worked on it

Thank you so much for the input haha
TLDR added the cache control header to the response in my middleware and now everything is working perfectly 😄

@Arecsu
Copy link

Arecsu commented Nov 6, 2024

hey @JusticeMatthew, just to know, what cache-control headers did you add and how? My HTML files have cache-control: public, max-age=0, must-revalidate but seems like prefetch is a hit and miss on every browser with those settings. This is prefetch with the settings on "load" and "viewport". The page: https://malejandro.com

For instance, the first page load, it prefetchs the links but only works on Chromium browsers (sometimes). And even on Chromium, once you start navigating through the page, seems like the previously prefetched pages are discarded and the browser will navigate to them without prefetching at all, like standard browser navigation.

This is being solved if I set a value > 0 to cache-control to those HTML documents. Then it works great on pretty much every browser, But I don't think that would be a good idea to set cache-control to HTML documents?

EDIT: also on "hover". Links are being prefetched only one time and never prefetched again unless the whole page is refreshed. This might be intended, but this would mean we have to set HTML files with cache-control to a value >0, preferable high enough for the expected navigation duration of the page.

To sum this up:
with HTML documents set to cache-control: public, max-age=0, must-revalidate

  • Firefox won't make usage of those prefetched pages at all.
  • Chromium will use them only once, and after navigating through the page in one session, it will no longer prefetch previously navigated pages. Try going to https://malejandro.com to one of those "Work" links and then back and forth to the homepage with the link in the header. At some point, it will make new requests for every link like a standard browsing navigation.

Might be a good idea to add a check for the headers in Astro Router to re-prefetch pages when their cache expires, but this would only work on Chromium as Firefox throws a "NS_BINDING_ABORTED" due to, possibly, cache-control being set to max-age=0

@bluwy would love to hear what are your thoughts on this, because the docs seem to assume Chrome and Firefox will handle this smoothly no matter what cache-control values are as long as they exist.

With cache-control set to a higher value, let's say "max-age: 6000"

  • Both Firefox and Chromium works beautifully. Prefetching links only once and the browser will re-use the HTML documents by itself.
  • Consequences: HTML document might be updated on the server and clients can potentially being stuck with previous version, until cache expires or cache is invalidated properly from the CDN manually, among other unintended consequences possibly.

Could not test Safari.

@bluwy
Copy link
Member

bluwy commented Nov 6, 2024

If you've set max-age=0, isn't that like not setting a cache control at all? You don't have to set too high, even max-age: 5 should be enough as you're not taking a long time between the start of prefetching and the actual navigation.

Might be a good idea to add a check for the headers in Astro Router to re-prefetch pages when their cache expires

I did want to try that, but the browser doesn't provide APIs to read that for prefetches or fetches. It's all managed by the browser itself.

I'd wish there's a better DX to setup prefetching that works everywhere, but after research in the past this is the best I've found.

@Arecsu
Copy link

Arecsu commented Nov 6, 2024

Ah sorry, I interpreted cache-control could have any value as long as it exists. To add to your point, max-age: 5 might work for links which are being focused or hovered, but given that the current implementation will only prefetch the link once, the act of going back and forth between links in a single session will have those documents already expired. The browser API won't save from it as you pointed out, unless the value of cache-control is greater enough to cover an entire browsing session.

I appreciate your feedback a lot! Even if a custom prefetching replace to browsers APIs could be done, I don't think it is even worth it given the increase in complexity and bugs. Using a value for cache-control seems more reasonable.

@JusticeMatthew
Copy link
Author

@Arecsu what @bluwy said!

I literally set a max age of 1 to get it working

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage Issue needs to be triaged
Projects
None yet
Development

No branches or pull requests

4 participants