Add `alwaysThrottleRetries` flag (#26685)
This puts the change introduced by #26611 behind a flag until Meta is able to roll it out. Disabling the flag reverts back to the old behavior, where retries are throttled if there's still data remaining in the tree, but not if all the data has finished loading. The new behavior is still enabled in the public builds.
This commit is contained in:
parent
7f8c501f68
commit
d73d7d5908
|
@ -39,6 +39,7 @@ import {
|
|||
enableTransitionTracing,
|
||||
useModernStrictMode,
|
||||
disableLegacyContext,
|
||||
alwaysThrottleRetries,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
||||
import is from 'shared/objectIs';
|
||||
|
@ -1115,7 +1116,10 @@ function finishConcurrentRender(
|
|||
workInProgressTransitions,
|
||||
);
|
||||
} else {
|
||||
if (includesOnlyRetries(lanes)) {
|
||||
if (
|
||||
includesOnlyRetries(lanes) &&
|
||||
(alwaysThrottleRetries || exitStatus === RootSuspended)
|
||||
) {
|
||||
// This render only included retries, no updates. Throttle committing
|
||||
// retries so that we don't show too many loading states too quickly.
|
||||
const msUntilTimeout =
|
||||
|
|
|
@ -1779,10 +1779,28 @@ describe('ReactSuspenseWithNoopRenderer', () => {
|
|||
await resolveText('B');
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span prop="Loading..." />);
|
||||
|
||||
// Restart and render the complete content. The tree will finish but we
|
||||
// won't commit the result yet because the fallback appeared recently.
|
||||
// Restart and render the complete content.
|
||||
await waitForAll(['A', 'B']);
|
||||
|
||||
if (gate(flags => flags.alwaysThrottleRetries)) {
|
||||
// Correct behavior:
|
||||
//
|
||||
// The tree will finish but we won't commit the result yet because the fallback appeared recently.
|
||||
expect(ReactNoop).toMatchRenderedOutput(<span prop="Loading..." />);
|
||||
} else {
|
||||
// Old behavior, gated until this rolls out at Meta:
|
||||
//
|
||||
// TODO: Because this render was the result of a retry, and a fallback
|
||||
// was shown recently, we should suspend and remain on the fallback for
|
||||
// little bit longer. We currently only do this if there's still
|
||||
// remaining fallbacks in the tree, but we should do it for all retries.
|
||||
expect(ReactNoop).toMatchRenderedOutput(
|
||||
<>
|
||||
<span prop="A" />
|
||||
<span prop="B" />
|
||||
</>,
|
||||
);
|
||||
}
|
||||
});
|
||||
assertLog([]);
|
||||
expect(ReactNoop).toMatchRenderedOutput(
|
||||
|
|
|
@ -124,6 +124,8 @@ export const diffInCommitPhase = __EXPERIMENTAL__;
|
|||
|
||||
export const enableAsyncActions = __EXPERIMENTAL__;
|
||||
|
||||
export const alwaysThrottleRetries = true;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Chopping Block
|
||||
//
|
||||
|
|
|
@ -22,6 +22,7 @@ import typeof * as DynamicFlagsType from 'ReactNativeInternalFeatureFlags';
|
|||
|
||||
export const enableUseRefAccessWarning = __VARIANT__;
|
||||
export const enableDeferRootSchedulingToMicrotask = __VARIANT__;
|
||||
export const alwaysThrottleRetries = __VARIANT__;
|
||||
|
||||
// Flow magic to verify the exports of this file match the original version.
|
||||
((((null: any): ExportsType): DynamicFlagsType): ExportsType);
|
||||
|
|
|
@ -17,8 +17,11 @@ import * as dynamicFlags from 'ReactNativeInternalFeatureFlags';
|
|||
|
||||
// We destructure each value before re-exporting to avoid a dynamic look-up on
|
||||
// the exports object every time a flag is read.
|
||||
export const {enableUseRefAccessWarning, enableDeferRootSchedulingToMicrotask} =
|
||||
dynamicFlags;
|
||||
export const {
|
||||
enableUseRefAccessWarning,
|
||||
enableDeferRootSchedulingToMicrotask,
|
||||
alwaysThrottleRetries,
|
||||
} = dynamicFlags;
|
||||
|
||||
// The rest of the flags are static for better dead code elimination.
|
||||
export const enableDebugTracing = false;
|
||||
|
|
|
@ -75,5 +75,7 @@ export const enableDeferRootSchedulingToMicrotask = true;
|
|||
export const diffInCommitPhase = true;
|
||||
export const enableAsyncActions = false;
|
||||
|
||||
export const alwaysThrottleRetries = true;
|
||||
|
||||
// Flow magic to verify the exports of this file match the original version.
|
||||
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
|
||||
|
|
|
@ -75,5 +75,7 @@ export const enableDeferRootSchedulingToMicrotask = true;
|
|||
export const diffInCommitPhase = true;
|
||||
export const enableAsyncActions = false;
|
||||
|
||||
export const alwaysThrottleRetries = true;
|
||||
|
||||
// Flow magic to verify the exports of this file match the original version.
|
||||
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
|
||||
|
|
|
@ -72,5 +72,7 @@ export const enableDeferRootSchedulingToMicrotask = true;
|
|||
export const diffInCommitPhase = true;
|
||||
export const enableAsyncActions = false;
|
||||
|
||||
export const alwaysThrottleRetries = true;
|
||||
|
||||
// Flow magic to verify the exports of this file match the original version.
|
||||
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
|
||||
|
|
|
@ -77,5 +77,7 @@ export const enableDeferRootSchedulingToMicrotask = true;
|
|||
export const diffInCommitPhase = true;
|
||||
export const enableAsyncActions = false;
|
||||
|
||||
export const alwaysThrottleRetries = true;
|
||||
|
||||
// Flow magic to verify the exports of this file match the original version.
|
||||
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
|
||||
|
|
|
@ -27,6 +27,7 @@ export const enableCustomElementPropertySupport = __VARIANT__;
|
|||
export const enableDeferRootSchedulingToMicrotask = __VARIANT__;
|
||||
export const diffInCommitPhase = __VARIANT__;
|
||||
export const enableAsyncActions = __VARIANT__;
|
||||
export const alwaysThrottleRetries = __VARIANT__;
|
||||
|
||||
// Enable this flag to help with concurrent mode debugging.
|
||||
// It logs information to the console about React scheduling, rendering, and commit phases.
|
||||
|
|
|
@ -30,6 +30,7 @@ export const {
|
|||
enableDeferRootSchedulingToMicrotask,
|
||||
diffInCommitPhase,
|
||||
enableAsyncActions,
|
||||
alwaysThrottleRetries,
|
||||
} = dynamicFeatureFlags;
|
||||
|
||||
// On WWW, __EXPERIMENTAL__ is used for a new modern build.
|
||||
|
|
|
@ -10,4 +10,5 @@
|
|||
declare module 'ReactNativeInternalFeatureFlags' {
|
||||
declare export var enableUseRefAccessWarning: boolean;
|
||||
declare export var enableDeferRootSchedulingToMicrotask: boolean;
|
||||
declare export var alwaysThrottleRetries: boolean;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue