187231ba refactor(router-core): clarify segment interpolation
Organize the generic interpolation loop into static, wildcard, and named-parameter behavior blocks. Keep one shared key lookup, one encoding step, and one prefix/value/suffix assembly. Name affix boundaries and keep optional/missing wildcard behavior local to its segment type.
Replace the self-clearing onMissing callback with an optional metadata result object. The public interpolatePath wrapper reuses its existing result object; pathname-only callers still allocate no metadata. Preserve one parameter read, the reusable parser buffer, absent optional cache keys, canonical and legacy splat metadata, and public return values. Fast-path empty splat strings before the URL-safe regex so sharing the encoding step does not penalize omitted values.
Final official gzip measurements versus 5017a72614:
- React minimal: 85771 -> 85769 (-2 bytes).
- React full: 89384 -> 89382 (-2 bytes).
- All 18 fixtures range from -4 to +8 bytes; no unrelated source changes compensate for interpolation cost.
Added mixed-type/affix metadata coverage and direct pathname-kernel benchmarks. Paired fixed-seed CPU measurements of the real parent/current modules show effectively flat required client pathname interpolation (+0.04%) and 0.37-4.14% lower time in the other sampled required/optional/splat/mixed/missing client/server combinations. These are focused kernel diagnostics, not a broad application speedup claim.
Preserve the experiments, rejected larger variants, full fixture metrics, and raw benchmark output in uncommitted LOG.md and session artifacts.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> 6678fa01 test(router): stabilize opt-in Link performance comparisons
Bound control navigation history with replace and assert that the measured anchors remain mounted. Share the exact setup, batch, and post-measurement assertions between normal Vitest benches and the paired comparison runner. Increase normal warm-up and measurement windows.
Add an opt-in stable runner with a fresh process per case/replica, separate router/app modules, one shared production React runtime, deterministic V8 random/hash seeds, alternating initialization order, and ABBA/BAAB fixed-work blocks. Record main-thread CPU, wall time, whole-process CPU, bundle hashes, and all raw blocks. Derive per-case 95% intervals from independent process replicas rather than correlated individual batches; require CPU and wall results to corroborate a direction.
Same-code controls exposed substantial noise in earlier methods. The selected control was centered near zero (client CPU -0.95%, SSR CPU -0.56%), with intervals still several percentage points wide. Keep unresolved measurements explicitly inconclusive instead of labeling them regressions.
Compared fixed runtime refs origin/main 28a5e4504e and bbaa7b3f29 across all 26 cases with four fresh-process replicas each: 16 cases support speedups, 10 remain inconclusive, and none support a slowdown in both metrics. Client middleware CPU: -5.95% [-13.89%, +2.73%]; SSR middleware: -16.06% [-31.65%, +3.09%]; SSR unique params: -5.08% [-14.97%, +5.96%]. These do not establish middleware or unique-param regressions.
No production package code or default CodSpeed workflow changes. Keep the complete raw matrix, calibration trials, snapshots, and detailed conclusions in uncommitted session artifacts and LOG.md.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> bbaa7b3f perf(router): meet the original Link bundle budgets
Move the bounded pathname cache onto RouterCore and reuse one interpolation traversal for pathname generation, cache keys, and optional public metadata. Remove the factory and per-parameter metadata callbacks, preserve decoder invalidation and development server/client overrides, and simplify React Link active-state and state-prop assembly. Public APIs and routing features remain unchanged.
Official gzip measurements against parent 37bd31e4e2:
- React minimal: 86000 -> 85772 bytes (-228), equal to origin/main.
- React full: 89601 -> 89356 bytes (-245), 6 below origin/main.
- All 18 Router/Start fixtures shrink by 130-245 gzip bytes. Link remains included; fixtures and the existing Link workload are unchanged.
- Independent Link-only changes save 78/86 bytes; core-only changes save 174/169. Combined gzip effects are not additive.
Fresh existing production Link benchmark, Apple M4 / Node 24.20.0 / Vitest 4.1.4: 200 persistent Links, eight navigations per batch, 50 warm-up iterations and 10-second measurements, with separate processes in counterbalanced order.
- Parent means: 2.903316, 2.908833, 2.945163, 2.955386 ms.
- This commit means: 2.941129, 2.941699, 2.920172, 2.970072 ms.
- Median run means: 2.926998 -> 2.941414 ms (+0.49% time, near process-to-process noise; no incremental Link speedup claimed). Maximum within-run RME: 0.84%.
- Fresh original-baseline comparison: 4.283454 -> 3.016571 ms (-29.58% time). This is the whole-series improvement, not the incremental effect of this commit.
Identical focused before/after benchmarks show public helper regressions eliminated, server public families 4.68-12.85% faster, and cached mixed/missing cases 6.50-10.43% faster. Removing the redundant last-template shortcut makes isolated single-template cache hits slower (5.93 -> 7.21 us client per 200 calls; 5.99 -> 6.83 us server). The real Link workload remains effectively flat for this size-reduction step.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>