Skip to content

Commit b070a68

Browse files
committed
fewer store updates in sync loadRouteMatch
1 parent 0c18913 commit b070a68

File tree

1 file changed

+43
-33
lines changed

1 file changed

+43
-33
lines changed

packages/router-core/src/load-matches.ts

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -709,9 +709,10 @@ const loadRouteMatch = (
709709
index: number,
710710
): Awaitable<AnyRouteMatch> => {
711711
const { id: matchId, routeId } = inner.matches[index]!
712-
let loaderShouldRunAsync = false
713-
let loaderIsRunningAsync = false
714712
const route = inner.router.looseRoutesById[routeId]!
713+
const prevMatch = inner.router.getMatch(matchId)!
714+
let loaderIsRunningAsync = false
715+
let nextPreload: undefined | boolean
715716

716717
if (shouldSkipLoader(inner, matchId)) {
717718
if (inner.router.isServer) {
@@ -725,13 +726,11 @@ const loadRouteMatch = (
725726
return inner.router.getMatch(matchId)!
726727
})
727728
}
728-
return inner.router.getMatch(matchId)!
729+
return prevMatch
729730
}
730731
return settleLoadRouteMatch()
731732
}
732733

733-
const prevMatch = inner.router.getMatch(matchId)!
734-
735734
// there is a loaderPromise, so we are in the middle of a load
736735
if (prevMatch._nonReactive.loaderPromise) {
737736
// do not block if we already have stale data we can show
@@ -770,25 +769,18 @@ const loadRouteMatch = (
770769
? shouldReloadOption(getLoaderContext(inner, matchId, index, route))
771770
: shouldReloadOption
772771

773-
const nextPreload =
772+
nextPreload =
774773
!!preload && !inner.router.state.matches.some((d) => d.id === matchId)
775-
const match = inner.router.getMatch(matchId)!
776-
match._nonReactive.loaderPromise = createControlledPromise<void>()
777-
if (nextPreload !== match.preload) {
778-
inner.updateMatch(matchId, (prev) => ({
779-
...prev,
780-
preload: nextPreload,
781-
}))
782-
}
774+
prevMatch._nonReactive.loaderPromise = createControlledPromise<void>()
783775

784776
if (preload && route.options.preload === false) {
785777
// Do nothing
786778
return settleLoadRouteMatch()
787779
}
788780

789781
// If the route is successful and still fresh, just resolve
790-
const { status, invalid } = match
791-
loaderShouldRunAsync =
782+
const { status, invalid } = prevMatch
783+
const loaderShouldRunAsync =
792784
status === 'success' && (invalid || (shouldReload ?? age > staleAge))
793785
if (loaderShouldRunAsync && !inner.sync) {
794786
loaderIsRunningAsync = true
@@ -809,6 +801,7 @@ const loadRouteMatch = (
809801
}
810802

811803
if (status !== 'success' || (loaderShouldRunAsync && inner.sync)) {
804+
updatePreload()
812805
return runLoader(inner, matchId, index, route).then(settleLoadRouteMatch)
813806
}
814807

@@ -818,16 +811,32 @@ const loadRouteMatch = (
818811
const headResult = executeHead(inner, matchId, route)
819812
if (headResult) {
820813
return headResult.then((head) => {
821-
inner.updateMatch(matchId, (prev) => ({
822-
...prev,
823-
...head,
824-
}))
825-
return settleLoadRouteMatch()
814+
let result: ReturnType<typeof settleLoadRouteMatch>
815+
batch(() => {
816+
inner.updateMatch(matchId, (prev) => ({
817+
...prev,
818+
...head,
819+
}))
820+
result = settleLoadRouteMatch()
821+
})
822+
return result!
826823
})
827824
}
828825

829826
return settleLoadRouteMatch()
830827

828+
function updatePreload() {
829+
if (nextPreload === undefined) return
830+
if (nextPreload !== prevMatch.preload) {
831+
const preload = nextPreload
832+
inner.updateMatch(matchId, (prev) => ({
833+
...prev,
834+
preload,
835+
}))
836+
}
837+
nextPreload = undefined
838+
}
839+
831840
function settleLoadRouteMatch() {
832841
const match = inner.router.getMatch(matchId)!
833842

@@ -843,15 +852,19 @@ const loadRouteMatch = (
843852

844853
const nextIsFetching = loaderIsRunningAsync ? match.isFetching : false
845854
if (nextIsFetching !== match.isFetching || match.invalid !== false) {
846-
inner.updateMatch(matchId, (prev) => ({
847-
...prev,
848-
isFetching: nextIsFetching,
849-
invalid: false,
850-
}))
851-
return inner.router.getMatch(matchId)!
855+
batch(() => {
856+
updatePreload()
857+
inner.updateMatch(matchId, (prev) => ({
858+
...prev,
859+
isFetching: nextIsFetching,
860+
invalid: false,
861+
}))
862+
})
863+
} else {
864+
updatePreload()
852865
}
853866

854-
return match
867+
return inner.router.getMatch(matchId)!
855868
}
856869
}
857870

@@ -886,13 +899,10 @@ export async function loadMatches(arg: {
886899

887900
// Execute all loaders in parallel
888901
const max = inner.firstBadMatchIndex ?? inner.matches.length
889-
let hasPromises = false
890902
for (let i = 0; i < max; i++) {
891-
const result = loadRouteMatch(inner, i)
892-
inner.matchPromises.push(result)
893-
if (!hasPromises && isPromise(result)) hasPromises = true
903+
inner.matchPromises.push(loadRouteMatch(inner, i))
894904
}
895-
if (hasPromises) await Promise.all(inner.matchPromises)
905+
await Promise.all(inner.matchPromises)
896906

897907
const readyPromise = triggerOnReady(inner)
898908
if (isPromise(readyPromise)) await readyPromise

0 commit comments

Comments
 (0)