perf: eliminate remaining URL construction and cache bot detection#91613
perf: eliminate remaining URL construction and cache bot detection#91613benfavre wants to merge 1 commit intovercel:canaryfrom
Conversation
Three targeted optimizations in the per-request hot path of base-server: 1. Replace `new URL(value, 'http://localhost')` with string-based `getPathname()` for extracting the pathname from the matched-path header and `req.url`. These are always relative URLs where we only need the path before '?'/'#'. Saves ~4 μs/req per call (two calls in the minimalMode path). 2. Derive `isBot` from the already-computed `botType` in `renderToResponseWithComponentsImpl` instead of running a second regex test against the user-agent string. `getBotType(ua)` is called in `renderImpl` and stored on `renderOpts.botType`; `isBot(ua)` is equivalent to `botType !== undefined`, so the second call is redundant. 3. Hoist six inline regex literals to module-level constants to avoid re-creation on every request: double-slash/backslash detection, index route matching, `/_next/` and `/static/` prefix tests, and trailing `.json` replacement. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Allow CI Workflow Run
Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer |
Performance ImpactProfiling setup: Node.js v25.7.0, Optimization 1: Replace
Optimization 2: Cache bot detection, compute once per request
Test Verification
|
Regression SafetyZero regression risk. String-based pathname extraction produces identical results to BenchmarkEliminates 2 URL constructions + 1 redundant bot regex test + 6 inline regex recompilations per request. Each saves 1-4μs at 7,000+ req/s. Test Verification
|
Summary
Three targeted optimizations in the per-request hot path of
base-server.ts:new URL()with string-based pathname extraction — The matched-path header andreq.urlare always relative URLs; we only need the path before?/#. A simpleindexOf+slicereplaces twonew URL(value, 'http://localhost')calls in the minimalMode path, saving ~4 μs per call.isBotfrom already-computedbotType—getBotType(ua)runs inrenderImpland stores the result onrenderOpts.botType. Later,renderToResponseWithComponentsImplre-reads the user-agent and callsisBot(ua)which runs the same regex again. SinceisBot(ua) === (getBotType(ua) !== undefined), we now useopts.botType !== undefinedinstead — zero additional regex work./pattern/literals in per-request code paths (slash normalization, index route detection,/_next/and/static/prefix tests,.jsonsuffix stripping) are moved to module-level constants to avoid re-creation overhead.Test plan
required-server-files*.test.ts) pass — these exercise the matched-path header code pathisBotresult derived frombotTypewhich uses identical logic (getBotTypereturnsundefinediffisBotreturnsfalse)🤖 Generated with Claude Code