cheeaun / phanpy

A minimalistic opinionated Mastodon web client
https://phanpy.social
MIT License
945 stars 85 forks source link

Phanpy sends large numbers of OPTIONS HTTP requests when making Mastodon API calls #589

Open VyrCossont opened 5 days ago

VyrCossont commented 5 days ago

Describe the bug

To Reproduce

  1. Open browser dev tools or an HTTP proxy tool. Filter to XHR if possible.
  2. Open Phanpy.
  3. Interact with the app: scroll the timeline, view a thread, view a user, etc.
  4. See about one OPTIONS request before almost any other API call HTTP request.

Expected behavior Phanpy should not send so many OPTIONS requests. This causes unnecessary network traffic and unnecessary work for the server, and might result in Phanpy (and other clients sharing the same IP, including other Phanpy instances) getting rate limited.

Screenshots Firefox dev tools showing about one `OPTIONS` HTTP request before any other HTTP request

Desktop:

Additional context I'm guessing this is part of Mastodon API feature detection, but it shouldn't be necessary to preflight literally every API route. Even caching the results for a given API route for a few minutes would help a lot.

VyrCossont commented 5 days ago

On further investigation, this looks like CORS preflighting, not API feature detection. However, other web-based Mastodon clients such as the official Mastodon webapp, Semaphore, and Elk don't trigger anywhere near as many CORS preflight requests, and Elk uses the same Mastodon client, so it seems specific to Phanpy.

Same issue on Chrome 126.0.6478.127. It does not appear to happen in Safari 17.5 (19618.2.12.11.6), although Safari's dev tools don't show CORS preflight requests so I had to use Proxyman to check this.

cheeaun commented 5 days ago

@VyrCossont

  1. Is the devtools network tab configured differently when you debug this on Phanpy? For this to only happen on Phanpy and not on other web clients is weird. One possible thing that I could think of is that "Disable cache" is turned on when you debug network calls on Phanpy.
  2. Will need to check the CORS headers. Usually Access-Control-Max-Age will prevent the browser from constantly sending preflight requests.
VyrCossont commented 5 days ago

@cheeaun

  1. Configured identically, and I've confirmed that the disable cache checkbox is not checked. Same results in browser-independent tools like Proxyman.
  2. That's what I assumed too, but with either GtS or Mastodon backends (testing against mastodon.social) I'm seeing apparently valid Access-Control-Max-Age headers in the responses.

It's possible this is down to Phanpy being much more chatty than other clients: I'm seeing a lot of requests for individual accounts and statuses by ID when I scroll the timeline, which all have unique URLs (since the account or status ID is part of the URL path), and thus wouldn't benefit from the ACMA header unless the exact same thing was fetched again. Is there some reason Phanpy is fetching those individually, instead of using the accounts and statuses returned in a given timeline span?

cheeaun commented 4 days ago

Hmm, possible 🤔. These are the reasons for those individual fetches:

Post fetches:

  1. Quote posts — any links in the post that may look like a post link
  2. Reply hints — shows a small preview of the post above the post that's replying to it.
  3. Thread count indicator — shows the "index" of the post in a thread by fetching the replied-to post. It'll max to 3 fetches before giving up, as some threads are very long.

Account fetches:

  1. At-mention indicator — shows when a post has inReplyToAccountId but mentions is empty, usually when folks reply without putting at-mentions text in the post content.

Since the start of development, I've carefully added these features one-by-one as to not accidentally exceed the API rate limit, by observing user feedback. The fetches are also throttled with 1s interval and cached in-memory.