mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-10-30 00:27:11 +09:00
This is the change behind the headline symptom. A DevTools capture of /domains
showed ~70s of network activity and a 404 taking 28.77 SECONDS. The backend
measured that same request at 1.0ms in its own api_usage_logs table. A routing
404 runs no handler and touches no database, so it cannot spend 28s working —
the entire gap was Stalled/Queueing in the browser.
The cause: in dev the API was same-origin with the Vite dev server, which serves
each of the ~760 source files as its own request. A browser allows six
concurrent HTTP/1.1 connections per origin, so twenty API calls queued behind
hundreds of module requests. Splitting the origin doubles the usable sockets
and, more to the point, stops a slow API call from blocking a JS module.
Same-origin was not an arbitrary choice — the comment it replaces warned about
"CORS/preflight redirects". Both halves of that are handled:
- CORS: config.py DEFAULT_CORS_ORIGINS already lists the Vite dev origin on
both localhost and 127.0.0.1, so nothing new is being allowed.
- Preflight: every panel request carries an Authorization header, which makes
it non-simple. Without Access-Control-Max-Age the browser re-runs the
preflight every few seconds (Chrome caches 5s by default), so a cross-origin
panel would pay two round trips per call forever — worse than what it
replaces. CORS now sends max_age=3600, verified against the real create_app()
rather than assumed: a preflight from http://localhost:41921 returns 200 with
Access-Control-Max-Age: 3600 and the matching allow-origin. That header is
worth having regardless, since any deployment serving the panel from a
different origin than the API was paying the same tax.
Escape hatch: VITE_API_PROXY=true restores same-origin for a setup with an
origin CORS does not expect. Socket.IO is deliberately untouched — it stays on
window.location.origin in dev, because a WebSocket upgrades out of the HTTP
connection pool and gains nothing from the split.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>