Skip to content

Commit e23d6cb

Browse files
authored
Optimization to avoid redundant calls to matchRoutes (#12800)
1 parent 8f42290 commit e23d6cb

File tree

4 files changed

+26
-5
lines changed

4 files changed

+26
-5
lines changed

.changeset/smooth-mangos-act.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"react-router": patch
3+
---
4+
5+
Optimize route matching by skipping redundant `matchRoutes` calls when possible

packages/react-router/__tests__/dom/ssr/components-test.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,10 @@ describe("<NavLink />", () => {
150150

151151
describe("<ServerRouter>", () => {
152152
it("handles empty default export objects from the compiler", async () => {
153-
let staticHandlerContext = await createStaticHandler([{ path: "/" }]).query(
154-
new Request("http://localhost/")
155-
);
153+
let staticHandlerContext = await createStaticHandler([
154+
{ id: "root", path: "/", children: [{ id: "empty", index: true }] },
155+
]).query(new Request("http://localhost/"));
156+
156157
invariant(
157158
!(staticHandlerContext instanceof Response),
158159
"Expected a context"

packages/react-router/lib/hooks.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import type {
3131
} from "./router/router";
3232
import { IDLE_BLOCKER } from "./router/router";
3333
import type {
34+
AgnosticRouteMatch,
3435
ParamParseKey,
3536
Params,
3637
PathMatch,
@@ -534,7 +535,12 @@ export function useRoutesImpl(
534535
remainingPathname = "/" + segments.slice(parentSegments.length).join("/");
535536
}
536537

537-
let matches = matchRoutes(routes, { pathname: remainingPathname });
538+
let matches =
539+
dataRouterState &&
540+
dataRouterState.matches &&
541+
dataRouterState.matches.length > 0
542+
? (dataRouterState.matches as AgnosticRouteMatch<string, RouteObject>[])
543+
: matchRoutes(routes, { pathname: remainingPathname });
538544

539545
if (ENABLE_DEV_WARNINGS) {
540546
warning(

packages/react-router/lib/router/router.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,7 @@ export function createRouter(init: RouterInit): Router {
838838
let initialScrollRestored = init.hydrationData != null;
839839

840840
let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);
841+
let initialMatchesIsFOW = false;
841842
let initialErrors: RouteData | null = null;
842843

843844
if (initialMatches == null && !patchRoutesOnNavigationImpl) {
@@ -882,6 +883,7 @@ export function createRouter(init: RouterInit): Router {
882883
init.history.location.pathname
883884
);
884885
if (fogOfWar.active && fogOfWar.matches) {
886+
initialMatchesIsFOW = true;
885887
initialMatches = fogOfWar.matches;
886888
}
887889
} else if (initialMatches.some((m) => m.route.lazy)) {
@@ -1521,7 +1523,14 @@ export function createRouter(init: RouterInit): Router {
15211523

15221524
let routesToUse = inFlightDataRoutes || dataRoutes;
15231525
let loadingNavigation = opts && opts.overrideNavigation;
1524-
let matches = matchRoutes(routesToUse, location, basename);
1526+
let matches =
1527+
opts?.initialHydration &&
1528+
state.matches &&
1529+
state.matches.length > 0 &&
1530+
!initialMatchesIsFOW
1531+
? // `matchRoutes()` has already been called if we're in here via `router.initialize()`
1532+
state.matches
1533+
: matchRoutes(routesToUse, location, basename);
15251534
let flushSync = (opts && opts.flushSync) === true;
15261535

15271536
let fogOfWar = checkFogOfWar(matches, routesToUse, location.pathname);

0 commit comments

Comments
 (0)