perf: optimize resolveParentParams lookups#718
Conversation
- Use Map<pattern, route> index for O(1) route lookups (was O(N) linear scan) - Use pre-computed patternParts instead of re-splitting pattern string - Pre-compute last dynamic segment index (was per-iteration slice+some)
Cover fully static routes, single-segment dynamic routes, and catch-all child segments.
- Remove dead ParentSegment.params field (allocated but never read) - Replace slice+join with incremental prefix string building - Export StaticParamsMap type so tests derive from source - Improve comment to explain WHY last segment is excluded
commit: |
|
/bigbonk review |
|
Review submitted successfully. Here's a summary of what I reviewed and commented on: Overall assessment: The PR is a clean, correct refactor. The logic transformation from O(N) Two minor comments posted:
|
- Move StaticParamsMap type above JSDoc block so the function comment sits directly above resolveParentParams (was erroneously separating them) - Declare 'part' before building prefixPattern so it's used for both the prefix string concatenation and the startsWith check, avoiding redundant array indexing
|
/bigbonk review |
There was a problem hiding this comment.
Clean, correct refactor. The O(1) Map lookup, incremental prefix building, and dead field removal are all straightforward wins. The new unit tests are thorough and cover the right edge cases.
CI is green (unit tests pass, integration tests pending at time of review but the relevant Vitest (unit) shard passed).
The two nits from the previous review (detached JSDoc, line swap for part reuse) are worth addressing but not blocking. One additional minor observation below.
| params: parts | ||
| .filter((p) => p.startsWith(":")) | ||
| .map((p) => p.replace(/^:/, "").replace(/[+*]$/, "")), | ||
| patternParts: parts, |
There was a problem hiding this comment.
Ultra-minor: this mockRoute helper manually constructs every field of AppRoute. If AppRoute gains new required fields in the future, this will silently fail to compile or — worse — produce a confusing test failure rather than a clear type error.
Consider adding satisfies AppRoute to the return (TypeScript 4.9+) so the compiler catches any shape drift immediately:
| patternParts: parts, | |
| } satisfies AppRoute; |
|
Review submitted. Here's a summary of my review: Approved the PR. The refactor is clean and correct:
The 9 unit tests cover the key edge cases well (no parents, missing pagePath, missing generateStaticParams, single parent, two-level nesting, static segments between dynamic parents, fully static routes, single-segment dynamic, catch-all child). I left one additional minor suggestion: adding |
Summary
allRoutes.find())patternPartsfromAppRouteinstead of re-splitting the pattern string on every callslice().some()allocation)slice(0, i+1).join("/")per dynamic segmentParentSegment.paramsfield (allocated but never read)StaticParamsMaptype for reuse across production code and testsThese are in-memory micro-optimizations (~1ms savings on a 500-route site). The expensive HTTP fetches are already deduplicated by
staticParamsCache. The wins are small but the code is cleaner — fewer allocations, O(1) lookups, and no dead fields.Partially addresses #563 (ticks the
resolveParentParamslookups checkbox).Test plan
resolveParentParamscovering: no parents, missing pagePath, missing generateStaticParams, single parent, two-level nesting, static segments between dynamic parents, fully static routes, single-segment dynamic routes, catch-all child segmentstests/prerender.test.tsintegration suite passes (including nested/shop/[category]/[item]top-down params)