@@ -212,6 +212,7 @@ let workInProgressRootExitStatus: RootExitStatus = RootIncomplete;
212
212
// because we deal mostly with expiration times in the hot path, so this avoids
213
213
// the conversion happening in the hot path.
214
214
let workInProgressRootLatestProcessedExpirationTime : ExpirationTime = Sync ;
215
+ let workInProgressRootLatestSuspenseTimeout : ExpirationTime = Sync ;
215
216
let workInProgressRootCanSuspendUsingConfig : null | SuspenseConfig = null ;
216
217
217
218
let nextEffect : Fiber | null = null ;
@@ -734,6 +735,7 @@ function prepareFreshStack(root, expirationTime) {
734
735
renderExpirationTime = expirationTime ;
735
736
workInProgressRootExitStatus = RootIncomplete ;
736
737
workInProgressRootLatestProcessedExpirationTime = Sync ;
738
+ workInProgressRootLatestSuspenseTimeout = Sync ;
737
739
workInProgressRootCanSuspendUsingConfig = null ;
738
740
739
741
if ( __DEV__ ) {
@@ -949,6 +951,7 @@ function renderRoot(
949
951
workInProgressRootExitStatus === RootSuspendedWithDelay ;
950
952
let msUntilTimeout = computeMsUntilTimeout (
951
953
workInProgressRootLatestProcessedExpirationTime ,
954
+ workInProgressRootLatestSuspenseTimeout ,
952
955
expirationTime ,
953
956
workInProgressRootCanSuspendUsingConfig ,
954
957
shouldDelay ,
@@ -973,14 +976,14 @@ function renderRoot(
973
976
// The work completed. Ready to commit.
974
977
if (
975
978
! isSync &&
976
- workInProgressRootLatestProcessedExpirationTime !== Sync &&
979
+ workInProgressRootLatestSuspenseTimeout !== Sync &&
977
980
workInProgressRootCanSuspendUsingConfig !== null
978
981
) {
979
982
// If we have exceeded the minimum loading delay, which probably
980
983
// means we have shown a spinner already, we might have to suspend
981
984
// a bit longer to ensure that the spinner is shown for enough time.
982
985
const msUntilTimeout = computeMsUntilSuspenseLoadingDelay (
983
- workInProgressRootLatestProcessedExpirationTime ,
986
+ workInProgressRootLatestSuspenseTimeout ,
984
987
expirationTime ,
985
988
workInProgressRootCanSuspendUsingConfig ,
986
989
) ;
@@ -1011,15 +1014,12 @@ export function markRenderEventTimeAndConfig(
1011
1014
workInProgressRootLatestProcessedExpirationTime = expirationTime ;
1012
1015
}
1013
1016
if ( suspenseConfig !== null ) {
1014
- // Most of the time we only have one config and getting wrong is not bad.
1015
- // We pick the config with the lowest timeout because we'll use it to
1016
- // reverse engineer the event time if we end up using JND and we want to
1017
- // error on the side of suspending less time.
1018
1017
if (
1019
- workInProgressRootCanSuspendUsingConfig === null ||
1020
- workInProgressRootCanSuspendUsingConfig . timeoutMs <
1021
- suspenseConfig . timeoutMs
1018
+ expirationTime < workInProgressRootLatestSuspenseTimeout &&
1019
+ expirationTime > Never
1022
1020
) {
1021
+ workInProgressRootLatestSuspenseTimeout = expirationTime ;
1022
+ // Most of the time we only have one config and getting wrong is not bad.
1023
1023
workInProgressRootCanSuspendUsingConfig = suspenseConfig ;
1024
1024
}
1025
1025
}
@@ -1974,7 +1974,7 @@ function jnd(timeElapsed: number) {
1974
1974
}
1975
1975
1976
1976
function computeMsUntilSuspenseLoadingDelay (
1977
- mostRecentEventTime : ExpirationTime ,
1977
+ latestTimeout : ExpirationTime ,
1978
1978
committedExpirationTime : ExpirationTime ,
1979
1979
suspenseConfig : SuspenseConfig ,
1980
1980
) {
@@ -1992,7 +1992,7 @@ function computeMsUntilSuspenseLoadingDelay(
1992
1992
// Compute the time until this render pass would expire.
1993
1993
const currentTimeMs : number = now ( ) ;
1994
1994
const eventTimeMs : number = inferTimeFromExpirationTime (
1995
- mostRecentEventTime ,
1995
+ latestTimeout ,
1996
1996
suspenseConfig ,
1997
1997
) ;
1998
1998
const timeElapsed = currentTimeMs - eventTimeMs ;
@@ -2008,6 +2008,7 @@ function computeMsUntilSuspenseLoadingDelay(
2008
2008
2009
2009
function computeMsUntilTimeout (
2010
2010
mostRecentEventTime : ExpirationTime ,
2011
+ suspenseTimeout : ExpirationTime ,
2011
2012
committedExpirationTime : ExpirationTime ,
2012
2013
suspenseConfig : null | SuspenseConfig ,
2013
2014
shouldDelay : boolean ,
@@ -2019,17 +2020,19 @@ function computeMsUntilTimeout(
2019
2020
2020
2021
// Compute the time until this render pass would expire.
2021
2022
const currentTimeMs : number = now ( ) ;
2022
- const timeUntilExpirationMs =
2023
- expirationTimeToMs ( committedExpirationTime ) - currentTimeMs ;
2024
2023
2025
- if ( suspenseConfig !== null && shouldDelay ) {
2026
- return timeUntilExpirationMs ;
2024
+ if ( suspenseTimeout !== Sync && shouldDelay ) {
2025
+ const timeUntilTimeoutMs =
2026
+ expirationTimeToMs ( suspenseTimeout ) - currentTimeMs ;
2027
+ return timeUntilTimeoutMs ;
2027
2028
}
2028
2029
2029
2030
const eventTimeMs : number = inferTimeFromExpirationTime (
2030
2031
mostRecentEventTime ,
2031
2032
suspenseConfig ,
2032
2033
) ;
2034
+ const timeUntilExpirationMs =
2035
+ expirationTimeToMs ( committedExpirationTime ) - currentTimeMs ;
2033
2036
let timeElapsed = currentTimeMs - eventTimeMs ;
2034
2037
if ( timeElapsed < 0 ) {
2035
2038
// We get this wrong some time since we estimate the time.
0 commit comments