Skip to content

feat(router-core) Path: performance improvements [PoC] #4682

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 14 commits into from
217 changes: 113 additions & 104 deletions packages/react-router/tests/link.bench.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ const InterpolatePathLink = ({
params,
children,
}: React.PropsWithChildren<LinkProps>) => {
const href = interpolatePath({ path: to, params }).interpolatedPath
const router = useRouter()
const href = interpolatePath({
path: to,
params,
encodePathParam: router.encodePathParam,
}).interpolatedPath
return <a href={href}>{children}</a>
}

Expand Down Expand Up @@ -70,117 +75,121 @@ describe.each([
// matchedParamId: 9999, // range from 0 to numberOfRoutes-1
// numberOfLinks: 15000,
// },
])('$name', ({ numberOfRoutes, numberOfLinks, matchedParamId }) => {
const renderRouter = createRouterRenderer(numberOfRoutes)

bench(
'hardcoded href',
() => {
const router = renderRouter(
Array.from({ length: numberOfLinks }).map((_, i) => (
<a key={i} href={`/params/${i}`}>
{i}
</a>
)),
)
render(<RouterProvider router={router} />)
},
{ warmupIterations: 1 },
)

bench(
'interpolate path',
() => {
const router = renderRouter(
Array.from({ length: numberOfLinks }).map((_, i) => (
<InterpolatePathLink
key={i}
to={`/params/$param${Math.min(i, matchedParamId)}`}
params={{ [`param${Math.min(i, matchedParamId)}`]: i }}
>
{i}
</InterpolatePathLink>
)),
)
render(<RouterProvider router={router} />)
},
{ warmupIterations: 1 },
)
])(
'$name',
{ concurrent: false, sequential: true },
({ numberOfRoutes, numberOfLinks, matchedParamId }) => {
const renderRouter = createRouterRenderer(numberOfRoutes)

bench(
'build location',
() => {
const router = renderRouter(
Array.from({ length: numberOfLinks }).map((_, i) => (
<BuildLocationLink
key={i}
to={`/params/$param${Math.min(i, matchedParamId)}`}
params={{ [`param${Math.min(i, matchedParamId)}`]: i }}
>
{i}
</BuildLocationLink>
)),
)
render(<RouterProvider router={router} />)
},
{ warmupIterations: 1 },
)
bench(
'hardcoded href',
() => {
const router = renderRouter(
Array.from({ length: numberOfLinks }).map((_, i) => (
<a key={i} href={`/params/${i}`}>
{i}
</a>
)),
)
render(<RouterProvider router={router} />)
},
{ warmupIterations: 1 },
)

bench(
'link to absolute path',
() => {
const router = renderRouter(
Array.from({ length: numberOfLinks }).map((_, i) => (
<Link
key={i}
to={`/params/$param${Math.min(i, matchedParamId)}`}
params={{ [`param${Math.min(i, matchedParamId)}`]: i }}
>
{i}
</Link>
)),
)
render(<RouterProvider router={router} />)
},
{ warmupIterations: 1 },
)
bench(
'interpolate path',
() => {
const router = renderRouter(
Array.from({ length: numberOfLinks }).map((_, i) => (
<InterpolatePathLink
key={i}
to={`/params/$param${Math.min(i, matchedParamId)}`}
params={{ [`param${Math.min(i, matchedParamId)}`]: i }}
>
{i}
</InterpolatePathLink>
)),
)
render(<RouterProvider router={router} />)
},
{ warmupIterations: 1 },
)

bench(
'link to relative path',
() => {
const router = renderRouter(
Array.from({ length: numberOfLinks }).map((_, i) => {
const to = `./params/$param${Math.min(i, matchedParamId)}`
bench(
'build location',
() => {
const router = renderRouter(
Array.from({ length: numberOfLinks }).map((_, i) => (
<BuildLocationLink
key={i}
to={`/params/$param${Math.min(i, matchedParamId)}`}
params={{ [`param${Math.min(i, matchedParamId)}`]: i }}
>
{i}
</BuildLocationLink>
)),
)
render(<RouterProvider router={router} />)
},
{ warmupIterations: 1 },
)

return (
bench(
'link to absolute path',
() => {
const router = renderRouter(
Array.from({ length: numberOfLinks }).map((_, i) => (
<Link
key={i}
from="/"
to={to}
to={`/params/$param${Math.min(i, matchedParamId)}`}
params={{ [`param${Math.min(i, matchedParamId)}`]: i }}
>
{i}
</Link>
)
}),
)
render(<RouterProvider router={router} />)
},
{ warmupIterations: 1 },
)
)),
)
render(<RouterProvider router={router} />)
},
{ warmupIterations: 1 },
)

bench(
'link to relative path',
() => {
const router = renderRouter(
Array.from({ length: numberOfLinks }).map((_, i) => {
const to = `./params/$param${Math.min(i, matchedParamId)}`

bench(
'link to current path',
() => {
const router = renderRouter(
Array.from({ length: numberOfLinks }).map((_, i) => (
<Link key={i} from="/" search={{ param: i }}>
{i}
</Link>
)),
)
render(<RouterProvider router={router} />)
},
{ warmupIterations: 1 },
)
})
return (
<Link
key={i}
from="/"
to={to}
params={{ [`param${Math.min(i, matchedParamId)}`]: i }}
>
{i}
</Link>
)
}),
)
render(<RouterProvider router={router} />)
},
{ warmupIterations: 1 },
)

bench(
'link to current path',
() => {
const router = renderRouter(
Array.from({ length: numberOfLinks }).map((_, i) => (
<Link key={i} from="/" search={{ param: i }}>
{i}
</Link>
)),
)
render(<RouterProvider router={router} />)
},
{ warmupIterations: 1 },
)
},
)
2 changes: 1 addition & 1 deletion packages/router-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export {
removeTrailingSlash,
exactPathTest,
resolvePath,
parsePathname,
cachedParsePathname as parsePathname,
interpolatePath,
matchPathname,
removeBasepath,
Expand Down
Loading
Loading