tl;dr: Cross-Origin Resource Sharing (CORS), a good practice enforced by browsers for security purposes is a performance slowdown. Thus, the next best thing you can do starting with the 2nd request, is to cache your OPTIONS preflight responses, but there’s a catch.

Here’s how you may think you can cache OPTIONS responses for 24 hours (86400 seconds). But caching for 24 hours doesn’t work in Chrome or Edge.

// Response
Access-Control-Max-Age: 86400

Problem is that regardless of the age that your server returns, Chromium limits the Access-Control-Max-Age to a maximum of 2 hours.

// Maximum cache expiry time. Even if a CORS-preflight response contains
// Access-Control-Max-Age header that specifies a longer expiry time, this
// maximum time is applied.
constexpr base::TimeDelta kMaxTimeout = base::Hours(2);