Hey @tjcrowder, this is a really excellent summary of the options Render makes available to you. We don’t have an official best practice, but I’d personally recommend either of the first two approaches. As you pointed out, the third approach works, but doesn’t get the benefits of a CDN. We’re planning to implement a feature that would let you more easily attach a CDN to a server (see CDN for static assets in backend apps | Feature Requests | Render), but functionally I imagine it will end up being pretty similar to the rewrite rule approach.
I’m surprised to hear that the rewrite rule approach was so slow. You’re correct that there’s an extra hop to the CDN, but our provider (fastly) has POPs all over the globe so we shouldn’t be seeing that much additional latency. If you’re willing to help, I’d be very eager to see if we can reproduce this in order to gain more insight into what’s causing the 10x slowdown.
As for CORS preflight requests, in practice they may not be too bad, especially if you have, say, a GraphQL API at a particular path rather than a REST API that uses many different paths. For what it’s worth, Render serves all traffic over HTTP/2 so “simple” requests can be multiplexed and we might make up for some of that unnecessary overhead.
Thanks for the great question!