From 64a93ff448ccfad286bd3397c8780cfd270af067 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Thu, 17 Dec 2020 17:00:02 -0500 Subject: [PATCH 1/2] Add back enableSchedulerTimeoutInWorkLoop flag --- .../src/ReactFiberWorkLoop.new.js | 295 ++++++++++++------ .../src/ReactFiberWorkLoop.old.js | 295 ++++++++++++------ packages/shared/ReactFeatureFlags.js | 2 + .../forks/ReactFeatureFlags.native-fb.js | 1 + .../forks/ReactFeatureFlags.native-oss.js | 1 + .../forks/ReactFeatureFlags.test-renderer.js | 1 + .../ReactFeatureFlags.test-renderer.native.js | 1 + .../ReactFeatureFlags.test-renderer.www.js | 1 + .../shared/forks/ReactFeatureFlags.testing.js | 1 + .../forks/ReactFeatureFlags.testing.www.js | 1 + .../forks/ReactFeatureFlags.www-dynamic.js | 1 + .../shared/forks/ReactFeatureFlags.www.js | 31 +- 12 files changed, 408 insertions(+), 223 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index 3c189a73dd76d..2e27ee18bb3c4 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -31,6 +31,7 @@ import { enableDebugTracing, enableSchedulingProfiler, enableScopeAPI, + enableSchedulerTimeoutInWorkLoop, } from 'shared/ReactFeatureFlags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import invariant from 'shared/invariant'; @@ -767,110 +768,196 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) { // This is the entry point for every concurrent task, i.e. anything that // goes through Scheduler. -function performConcurrentWorkOnRoot(root) { - if (enableProfilerTimer && enableProfilerNestedUpdatePhase) { - resetNestedUpdateFlag(); - } - - // Since we know we're in a React event, we can clear the current - // event time. The next update will compute a new event time. - currentEventTime = NoTimestamp; - currentEventWipLanes = NoLanes; - currentEventPendingLanes = NoLanes; - - invariant( - (executionContext & (RenderContext | CommitContext)) === NoContext, - 'Should not already be working.', - ); - - // Flush any pending passive effects before deciding which lanes to work on, - // in case they schedule additional work. - const originalCallbackNode = root.callbackNode; - const didFlushPassiveEffects = flushPassiveEffects(); - if (didFlushPassiveEffects) { - // Something in the passive effect phase may have canceled the current task. - // Check if the task node for this root was changed. - if (root.callbackNode !== originalCallbackNode) { - // The current task was canceled. Exit. We don't need to call - // `ensureRootIsScheduled` because the check above implies either that - // there's a new task, or that there's no remaining work on this root. - return null; - } else { - // Current task was not canceled. Continue. - } - } - - // Determine the next expiration time to work on, using the fields stored - // on the root. - let lanes = getNextLanes( - root, - root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes, - ); - if (lanes === NoLanes) { - // Defensive coding. This is never expected to happen. - return null; - } - - let exitStatus = renderRootConcurrent(root, lanes); - - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes, - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // So we'll throw out the current work and restart. - prepareFreshStack(root, NoLanes); - } else if (exitStatus !== RootIncomplete) { - if (exitStatus === RootErrored) { - executionContext |= RetryAfterError; - - // If an error occurred during hydration, - // discard server response and fall back to client side render. - if (root.hydrate) { - root.hydrate = false; - clearContainer(root.containerInfo); - } - - // If something threw an error, try rendering one more time. We'll render - // synchronously to block concurrent data mutations, and we'll includes - // all pending updates are included. If it still fails after the second - // attempt, we'll give up and commit the resulting tree. - lanes = getLanesToRetrySynchronouslyOnError(root); - if (lanes !== NoLanes) { - exitStatus = renderRootSync(root, lanes); - } - } - - if (exitStatus === RootFatalErrored) { - const fatalError = workInProgressRootFatalError; - prepareFreshStack(root, NoLanes); - markRootSuspended(root, lanes); - ensureRootIsScheduled(root, now()); - throw fatalError; - } - - // We now have a consistent tree. The next step is either to commit it, - // or, if something suspended, wait to commit it after a timeout. - const finishedWork: Fiber = (root.current.alternate: any); - root.finishedWork = finishedWork; - root.finishedLanes = lanes; - finishConcurrentRender(root, exitStatus, lanes); - } - - ensureRootIsScheduled(root, now()); - if (root.callbackNode === originalCallbackNode) { - // The task node scheduled for this root is the same one that's - // currently executed. Need to return a continuation. - return performConcurrentWorkOnRoot.bind(null, root); - } - return null; -} +function performConcurrentWorkOnRoot(root, didTimeout) { + if ( + enableProfilerTimer && + enableProfilerNestedUpdatePhase + ) { + resetNestedUpdateFlag(); + } + + // Since we know we're in a React event, we can clear the current + // event time. The next update will compute a new event time. + currentEventTime = NoTimestamp; + currentEventWipLanes = NoLanes; + currentEventPendingLanes = NoLanes; + + invariant( + (executionContext & + (RenderContext | + CommitContext)) === + NoContext, + 'Should not already be working.', + ); + + // Flush any pending passive effects before deciding which lanes to work on, + // in case they schedule additional work. + const originalCallbackNode = + root.callbackNode; + const didFlushPassiveEffects = flushPassiveEffects(); + if ( + didFlushPassiveEffects + ) { + // Something in the passive effect phase may have canceled the current task. + // Check if the task node for this root was changed. + if ( + root.callbackNode !== + originalCallbackNode + ) { + // The current task was canceled. Exit. We don't need to call + // `ensureRootIsScheduled` because the check above implies either that + // there's a new task, or that there's no remaining work on this root. + return null; + } else { + // Current task was not canceled. Continue. + } + } + + // Determine the next expiration time to work on, using the fields stored + // on the root. + let lanes = getNextLanes( + root, + root === + workInProgressRoot + ? workInProgressRootRenderLanes + : NoLanes, + ); + if ( + lanes === NoLanes + ) { + // Defensive coding. This is never expected to happen. + return null; + } + + // TODO: We only check `didTimeout` defensively, to account for a Scheduler + // bug we're still investigating. Once the bug in Scheduler is fixed, + // we can remove this, since we track expiration ourselves. + if ( + enableSchedulerTimeoutInWorkLoop && + didTimeout + ) { + // Something expired. Flush synchronously until there's no expired + // work left. + markRootExpired( + root, + lanes, + ); + // This will schedule a synchronous callback. + ensureRootIsScheduled( + root, + now(), + ); + return null; + } + + let exitStatus = renderRootConcurrent( + root, + lanes, + ); + + if ( + includesSomeLane( + workInProgressRootIncludedLanes, + workInProgressRootUpdatedLanes, + ) + ) { + // The render included lanes that were updated during the render phase. + // For example, when unhiding a hidden tree, we include all the lanes + // that were previously skipped when the tree was hidden. That set of + // lanes is a superset of the lanes we started rendering with. + // + // So we'll throw out the current work and restart. + prepareFreshStack( + root, + NoLanes, + ); + } else if ( + exitStatus !== + RootIncomplete + ) { + if ( + exitStatus === + RootErrored + ) { + executionContext |= RetryAfterError; + + // If an error occurred during hydration, + // discard server response and fall back to client side render. + if (root.hydrate) { + root.hydrate = false; + clearContainer( + root.containerInfo, + ); + } + + // If something threw an error, try rendering one more time. We'll render + // synchronously to block concurrent data mutations, and we'll includes + // all pending updates are included. If it still fails after the second + // attempt, we'll give up and commit the resulting tree. + lanes = getLanesToRetrySynchronouslyOnError( + root, + ); + if ( + lanes !== NoLanes + ) { + exitStatus = renderRootSync( + root, + lanes, + ); + } + } + + if ( + exitStatus === + RootFatalErrored + ) { + const fatalError = workInProgressRootFatalError; + prepareFreshStack( + root, + NoLanes, + ); + markRootSuspended( + root, + lanes, + ); + ensureRootIsScheduled( + root, + now(), + ); + throw fatalError; + } + + // We now have a consistent tree. The next step is either to commit it, + // or, if something suspended, wait to commit it after a timeout. + const finishedWork: Fiber = (root + .current + .alternate: any); + root.finishedWork = finishedWork; + root.finishedLanes = lanes; + finishConcurrentRender( + root, + exitStatus, + lanes, + ); + } + + ensureRootIsScheduled( + root, + now(), + ); + if ( + root.callbackNode === + originalCallbackNode + ) { + // The task node scheduled for this root is the same one that's + // currently executed. Need to return a continuation. + return performConcurrentWorkOnRoot.bind( + null, + root, + ); + } + return null; + } function finishConcurrentRender(root, exitStatus, lanes) { switch (exitStatus) { diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index 220b1598a10de..5046e03936002 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -33,6 +33,7 @@ import { enableSchedulingProfiler, enableScopeAPI, enableDoubleInvokingEffects, + enableSchedulerTimeoutInWorkLoop, } from 'shared/ReactFeatureFlags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import invariant from 'shared/invariant'; @@ -775,110 +776,196 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) { // This is the entry point for every concurrent task, i.e. anything that // goes through Scheduler. -function performConcurrentWorkOnRoot(root) { - if (enableProfilerTimer && enableProfilerNestedUpdatePhase) { - resetNestedUpdateFlag(); - } - - // Since we know we're in a React event, we can clear the current - // event time. The next update will compute a new event time. - currentEventTime = NoTimestamp; - currentEventWipLanes = NoLanes; - currentEventPendingLanes = NoLanes; - - invariant( - (executionContext & (RenderContext | CommitContext)) === NoContext, - 'Should not already be working.', - ); - - // Flush any pending passive effects before deciding which lanes to work on, - // in case they schedule additional work. - const originalCallbackNode = root.callbackNode; - const didFlushPassiveEffects = flushPassiveEffects(); - if (didFlushPassiveEffects) { - // Something in the passive effect phase may have canceled the current task. - // Check if the task node for this root was changed. - if (root.callbackNode !== originalCallbackNode) { - // The current task was canceled. Exit. We don't need to call - // `ensureRootIsScheduled` because the check above implies either that - // there's a new task, or that there's no remaining work on this root. - return null; - } else { - // Current task was not canceled. Continue. - } - } - - // Determine the next expiration time to work on, using the fields stored - // on the root. - let lanes = getNextLanes( - root, - root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes, - ); - if (lanes === NoLanes) { - // Defensive coding. This is never expected to happen. - return null; - } - - let exitStatus = renderRootConcurrent(root, lanes); - - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes, - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // So we'll throw out the current work and restart. - prepareFreshStack(root, NoLanes); - } else if (exitStatus !== RootIncomplete) { - if (exitStatus === RootErrored) { - executionContext |= RetryAfterError; - - // If an error occurred during hydration, - // discard server response and fall back to client side render. - if (root.hydrate) { - root.hydrate = false; - clearContainer(root.containerInfo); - } - - // If something threw an error, try rendering one more time. We'll render - // synchronously to block concurrent data mutations, and we'll includes - // all pending updates are included. If it still fails after the second - // attempt, we'll give up and commit the resulting tree. - lanes = getLanesToRetrySynchronouslyOnError(root); - if (lanes !== NoLanes) { - exitStatus = renderRootSync(root, lanes); - } - } - - if (exitStatus === RootFatalErrored) { - const fatalError = workInProgressRootFatalError; - prepareFreshStack(root, NoLanes); - markRootSuspended(root, lanes); - ensureRootIsScheduled(root, now()); - throw fatalError; - } - - // We now have a consistent tree. The next step is either to commit it, - // or, if something suspended, wait to commit it after a timeout. - const finishedWork: Fiber = (root.current.alternate: any); - root.finishedWork = finishedWork; - root.finishedLanes = lanes; - finishConcurrentRender(root, exitStatus, lanes); - } - - ensureRootIsScheduled(root, now()); - if (root.callbackNode === originalCallbackNode) { - // The task node scheduled for this root is the same one that's - // currently executed. Need to return a continuation. - return performConcurrentWorkOnRoot.bind(null, root); - } - return null; -} +function performConcurrentWorkOnRoot(root, didTimeout) { + if ( + enableProfilerTimer && + enableProfilerNestedUpdatePhase + ) { + resetNestedUpdateFlag(); + } + + // Since we know we're in a React event, we can clear the current + // event time. The next update will compute a new event time. + currentEventTime = NoTimestamp; + currentEventWipLanes = NoLanes; + currentEventPendingLanes = NoLanes; + + invariant( + (executionContext & + (RenderContext | + CommitContext)) === + NoContext, + 'Should not already be working.', + ); + + // Flush any pending passive effects before deciding which lanes to work on, + // in case they schedule additional work. + const originalCallbackNode = + root.callbackNode; + const didFlushPassiveEffects = flushPassiveEffects(); + if ( + didFlushPassiveEffects + ) { + // Something in the passive effect phase may have canceled the current task. + // Check if the task node for this root was changed. + if ( + root.callbackNode !== + originalCallbackNode + ) { + // The current task was canceled. Exit. We don't need to call + // `ensureRootIsScheduled` because the check above implies either that + // there's a new task, or that there's no remaining work on this root. + return null; + } else { + // Current task was not canceled. Continue. + } + } + + // Determine the next expiration time to work on, using the fields stored + // on the root. + let lanes = getNextLanes( + root, + root === + workInProgressRoot + ? workInProgressRootRenderLanes + : NoLanes, + ); + if ( + lanes === NoLanes + ) { + // Defensive coding. This is never expected to happen. + return null; + } + + // TODO: We only check `didTimeout` defensively, to account for a Scheduler + // bug we're still investigating. Once the bug in Scheduler is fixed, + // we can remove this, since we track expiration ourselves. + if ( + enableSchedulerTimeoutInWorkLoop && + didTimeout + ) { + // Something expired. Flush synchronously until there's no expired + // work left. + markRootExpired( + root, + lanes, + ); + // This will schedule a synchronous callback. + ensureRootIsScheduled( + root, + now(), + ); + return null; + } + + let exitStatus = renderRootConcurrent( + root, + lanes, + ); + + if ( + includesSomeLane( + workInProgressRootIncludedLanes, + workInProgressRootUpdatedLanes, + ) + ) { + // The render included lanes that were updated during the render phase. + // For example, when unhiding a hidden tree, we include all the lanes + // that were previously skipped when the tree was hidden. That set of + // lanes is a superset of the lanes we started rendering with. + // + // So we'll throw out the current work and restart. + prepareFreshStack( + root, + NoLanes, + ); + } else if ( + exitStatus !== + RootIncomplete + ) { + if ( + exitStatus === + RootErrored + ) { + executionContext |= RetryAfterError; + + // If an error occurred during hydration, + // discard server response and fall back to client side render. + if (root.hydrate) { + root.hydrate = false; + clearContainer( + root.containerInfo, + ); + } + + // If something threw an error, try rendering one more time. We'll render + // synchronously to block concurrent data mutations, and we'll includes + // all pending updates are included. If it still fails after the second + // attempt, we'll give up and commit the resulting tree. + lanes = getLanesToRetrySynchronouslyOnError( + root, + ); + if ( + lanes !== NoLanes + ) { + exitStatus = renderRootSync( + root, + lanes, + ); + } + } + + if ( + exitStatus === + RootFatalErrored + ) { + const fatalError = workInProgressRootFatalError; + prepareFreshStack( + root, + NoLanes, + ); + markRootSuspended( + root, + lanes, + ); + ensureRootIsScheduled( + root, + now(), + ); + throw fatalError; + } + + // We now have a consistent tree. The next step is either to commit it, + // or, if something suspended, wait to commit it after a timeout. + const finishedWork: Fiber = (root + .current + .alternate: any); + root.finishedWork = finishedWork; + root.finishedLanes = lanes; + finishConcurrentRender( + root, + exitStatus, + lanes, + ); + } + + ensureRootIsScheduled( + root, + now(), + ); + if ( + root.callbackNode === + originalCallbackNode + ) { + // The task node scheduled for this root is the same one that's + // currently executed. Need to return a continuation. + return performConcurrentWorkOnRoot.bind( + null, + root, + ); + } + return null; + } function finishConcurrentRender(root, exitStatus, lanes) { switch (exitStatus) { diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 519ea5015d7d8..ea1a03377e02c 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -141,3 +141,5 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; + +export const enableSchedulerTimeoutInWorkLoop = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 32b1e3d45d0a6..88ba86e0f7b56 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -56,6 +56,7 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; +export const enableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 701cfd745fe36..d8d01b1e58db0 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -55,6 +55,7 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; +export const enableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index fb16a242199d6..56eb405a4ea07 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -55,6 +55,7 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; +export const enableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js index c9e64734268a6..07fa3f20f1eab 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -55,6 +55,7 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; +export const enableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 546784ff88ede..6214dc8a600b6 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -55,6 +55,7 @@ export const enableDoubleInvokingEffects = true; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; +export const enableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js index 1d028ee23ca40..36606b8367a08 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.js @@ -55,6 +55,7 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; +export const enableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.testing.www.js b/packages/shared/forks/ReactFeatureFlags.testing.www.js index ed3c033e99fff..a1211cd565c5f 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.www.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.www.js @@ -55,6 +55,7 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; +export const enableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index ad4ff2bab7655..1937d94df8ddc 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -53,3 +53,4 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = __VARIANT__; export const enableProfilerNestedUpdateScheduledHook = __VARIANT__; +export const enableSchedulerTimeoutInWorkLoop = __VARIANT__; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 8db205e184369..fb30b645cdd7b 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -15,21 +15,22 @@ import typeof * as DynamicFeatureFlags from './ReactFeatureFlags.www-dynamic'; const dynamicFeatureFlags: DynamicFeatureFlags = require('ReactFeatureFlags'); export const { - debugRenderPhaseSideEffectsForStrictMode, - disableInputAttributeSyncing, - enableTrustedTypesIntegration, - disableSchedulerTimeoutBasedOnReactExpirationTime, - warnAboutSpreadingKeyToJSX, - replayFailedUnitOfWorkWithInvokeGuardedCallback, - enableFilterEmptyStringAttributesDOM, - enableLegacyFBSupport, - deferRenderPhaseUpdateToNextBatch, - decoupleUpdatePriorityFromScheduler, - enableDebugTracing, - enableDoubleInvokingEffects, - enableUseRefAccessWarning, - disableNativeComponentFrames, -} = dynamicFeatureFlags; + debugRenderPhaseSideEffectsForStrictMode, + disableInputAttributeSyncing, + enableTrustedTypesIntegration, + disableSchedulerTimeoutBasedOnReactExpirationTime, + warnAboutSpreadingKeyToJSX, + replayFailedUnitOfWorkWithInvokeGuardedCallback, + enableFilterEmptyStringAttributesDOM, + enableLegacyFBSupport, + deferRenderPhaseUpdateToNextBatch, + decoupleUpdatePriorityFromScheduler, + enableDebugTracing, + enableDoubleInvokingEffects, + enableUseRefAccessWarning, + disableNativeComponentFrames, + enableSchedulerTimeoutInWorkLoop, + } = dynamicFeatureFlags; // On WWW, __EXPERIMENTAL__ is used for a new modern build. // It's not used anywhere in production yet. From 793f4fc03f49c0b1e784defd8eaa161463040490 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Thu, 17 Dec 2020 17:04:25 -0500 Subject: [PATCH 2/2] Nvm, keep it as disableSchedulerTimeoutInWorkLoop --- .../src/ReactFiberWorkLoop.new.js | 306 +++++++----------- .../src/ReactFiberWorkLoop.old.js | 306 +++++++----------- packages/shared/ReactFeatureFlags.js | 2 +- .../forks/ReactFeatureFlags.native-fb.js | 2 +- .../forks/ReactFeatureFlags.native-oss.js | 2 +- .../forks/ReactFeatureFlags.test-renderer.js | 2 +- .../ReactFeatureFlags.test-renderer.native.js | 2 +- .../ReactFeatureFlags.test-renderer.www.js | 2 +- .../shared/forks/ReactFeatureFlags.testing.js | 2 +- .../forks/ReactFeatureFlags.testing.www.js | 2 +- .../forks/ReactFeatureFlags.www-dynamic.js | 2 +- .../shared/forks/ReactFeatureFlags.www.js | 32 +- 12 files changed, 257 insertions(+), 405 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index 2e27ee18bb3c4..e8d097e9ef563 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -31,7 +31,7 @@ import { enableDebugTracing, enableSchedulingProfiler, enableScopeAPI, - enableSchedulerTimeoutInWorkLoop, + disableSchedulerTimeoutInWorkLoop, } from 'shared/ReactFeatureFlags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import invariant from 'shared/invariant'; @@ -769,195 +769,121 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) { // This is the entry point for every concurrent task, i.e. anything that // goes through Scheduler. function performConcurrentWorkOnRoot(root, didTimeout) { - if ( - enableProfilerTimer && - enableProfilerNestedUpdatePhase - ) { - resetNestedUpdateFlag(); - } - - // Since we know we're in a React event, we can clear the current - // event time. The next update will compute a new event time. - currentEventTime = NoTimestamp; - currentEventWipLanes = NoLanes; - currentEventPendingLanes = NoLanes; - - invariant( - (executionContext & - (RenderContext | - CommitContext)) === - NoContext, - 'Should not already be working.', - ); - - // Flush any pending passive effects before deciding which lanes to work on, - // in case they schedule additional work. - const originalCallbackNode = - root.callbackNode; - const didFlushPassiveEffects = flushPassiveEffects(); - if ( - didFlushPassiveEffects - ) { - // Something in the passive effect phase may have canceled the current task. - // Check if the task node for this root was changed. - if ( - root.callbackNode !== - originalCallbackNode - ) { - // The current task was canceled. Exit. We don't need to call - // `ensureRootIsScheduled` because the check above implies either that - // there's a new task, or that there's no remaining work on this root. - return null; - } else { - // Current task was not canceled. Continue. - } - } - - // Determine the next expiration time to work on, using the fields stored - // on the root. - let lanes = getNextLanes( - root, - root === - workInProgressRoot - ? workInProgressRootRenderLanes - : NoLanes, - ); - if ( - lanes === NoLanes - ) { - // Defensive coding. This is never expected to happen. - return null; - } - - // TODO: We only check `didTimeout` defensively, to account for a Scheduler - // bug we're still investigating. Once the bug in Scheduler is fixed, - // we can remove this, since we track expiration ourselves. - if ( - enableSchedulerTimeoutInWorkLoop && - didTimeout - ) { - // Something expired. Flush synchronously until there's no expired - // work left. - markRootExpired( - root, - lanes, - ); - // This will schedule a synchronous callback. - ensureRootIsScheduled( - root, - now(), - ); - return null; - } - - let exitStatus = renderRootConcurrent( - root, - lanes, - ); - - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes, - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // So we'll throw out the current work and restart. - prepareFreshStack( - root, - NoLanes, - ); - } else if ( - exitStatus !== - RootIncomplete - ) { - if ( - exitStatus === - RootErrored - ) { - executionContext |= RetryAfterError; - - // If an error occurred during hydration, - // discard server response and fall back to client side render. - if (root.hydrate) { - root.hydrate = false; - clearContainer( - root.containerInfo, - ); - } - - // If something threw an error, try rendering one more time. We'll render - // synchronously to block concurrent data mutations, and we'll includes - // all pending updates are included. If it still fails after the second - // attempt, we'll give up and commit the resulting tree. - lanes = getLanesToRetrySynchronouslyOnError( - root, - ); - if ( - lanes !== NoLanes - ) { - exitStatus = renderRootSync( - root, - lanes, - ); - } - } - - if ( - exitStatus === - RootFatalErrored - ) { - const fatalError = workInProgressRootFatalError; - prepareFreshStack( - root, - NoLanes, - ); - markRootSuspended( - root, - lanes, - ); - ensureRootIsScheduled( - root, - now(), - ); - throw fatalError; - } - - // We now have a consistent tree. The next step is either to commit it, - // or, if something suspended, wait to commit it after a timeout. - const finishedWork: Fiber = (root - .current - .alternate: any); - root.finishedWork = finishedWork; - root.finishedLanes = lanes; - finishConcurrentRender( - root, - exitStatus, - lanes, - ); - } - - ensureRootIsScheduled( - root, - now(), - ); - if ( - root.callbackNode === - originalCallbackNode - ) { - // The task node scheduled for this root is the same one that's - // currently executed. Need to return a continuation. - return performConcurrentWorkOnRoot.bind( - null, - root, - ); - } - return null; - } + if (enableProfilerTimer && enableProfilerNestedUpdatePhase) { + resetNestedUpdateFlag(); + } + + // Since we know we're in a React event, we can clear the current + // event time. The next update will compute a new event time. + currentEventTime = NoTimestamp; + currentEventWipLanes = NoLanes; + currentEventPendingLanes = NoLanes; + + invariant( + (executionContext & (RenderContext | CommitContext)) === NoContext, + 'Should not already be working.', + ); + + // Flush any pending passive effects before deciding which lanes to work on, + // in case they schedule additional work. + const originalCallbackNode = root.callbackNode; + const didFlushPassiveEffects = flushPassiveEffects(); + if (didFlushPassiveEffects) { + // Something in the passive effect phase may have canceled the current task. + // Check if the task node for this root was changed. + if (root.callbackNode !== originalCallbackNode) { + // The current task was canceled. Exit. We don't need to call + // `ensureRootIsScheduled` because the check above implies either that + // there's a new task, or that there's no remaining work on this root. + return null; + } else { + // Current task was not canceled. Continue. + } + } + + // Determine the next expiration time to work on, using the fields stored + // on the root. + let lanes = getNextLanes( + root, + root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes, + ); + if (lanes === NoLanes) { + // Defensive coding. This is never expected to happen. + return null; + } + + // TODO: We only check `didTimeout` defensively, to account for a Scheduler + // bug we're still investigating. Once the bug in Scheduler is fixed, + // we can remove this, since we track expiration ourselves. + if (!disableSchedulerTimeoutInWorkLoop && didTimeout) { + // Something expired. Flush synchronously until there's no expired + // work left. + markRootExpired(root, lanes); + // This will schedule a synchronous callback. + ensureRootIsScheduled(root, now()); + return null; + } + + let exitStatus = renderRootConcurrent(root, lanes); + + if ( + includesSomeLane( + workInProgressRootIncludedLanes, + workInProgressRootUpdatedLanes, + ) + ) { + // The render included lanes that were updated during the render phase. + // For example, when unhiding a hidden tree, we include all the lanes + // that were previously skipped when the tree was hidden. That set of + // lanes is a superset of the lanes we started rendering with. + // + // So we'll throw out the current work and restart. + prepareFreshStack(root, NoLanes); + } else if (exitStatus !== RootIncomplete) { + if (exitStatus === RootErrored) { + executionContext |= RetryAfterError; + + // If an error occurred during hydration, + // discard server response and fall back to client side render. + if (root.hydrate) { + root.hydrate = false; + clearContainer(root.containerInfo); + } + + // If something threw an error, try rendering one more time. We'll render + // synchronously to block concurrent data mutations, and we'll includes + // all pending updates are included. If it still fails after the second + // attempt, we'll give up and commit the resulting tree. + lanes = getLanesToRetrySynchronouslyOnError(root); + if (lanes !== NoLanes) { + exitStatus = renderRootSync(root, lanes); + } + } + + if (exitStatus === RootFatalErrored) { + const fatalError = workInProgressRootFatalError; + prepareFreshStack(root, NoLanes); + markRootSuspended(root, lanes); + ensureRootIsScheduled(root, now()); + throw fatalError; + } + + // We now have a consistent tree. The next step is either to commit it, + // or, if something suspended, wait to commit it after a timeout. + const finishedWork: Fiber = (root.current.alternate: any); + root.finishedWork = finishedWork; + root.finishedLanes = lanes; + finishConcurrentRender(root, exitStatus, lanes); + } + + ensureRootIsScheduled(root, now()); + if (root.callbackNode === originalCallbackNode) { + // The task node scheduled for this root is the same one that's + // currently executed. Need to return a continuation. + return performConcurrentWorkOnRoot.bind(null, root); + } + return null; +} function finishConcurrentRender(root, exitStatus, lanes) { switch (exitStatus) { diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index 5046e03936002..331fe20ee10a4 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -33,7 +33,7 @@ import { enableSchedulingProfiler, enableScopeAPI, enableDoubleInvokingEffects, - enableSchedulerTimeoutInWorkLoop, + disableSchedulerTimeoutInWorkLoop, } from 'shared/ReactFeatureFlags'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import invariant from 'shared/invariant'; @@ -777,195 +777,121 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) { // This is the entry point for every concurrent task, i.e. anything that // goes through Scheduler. function performConcurrentWorkOnRoot(root, didTimeout) { - if ( - enableProfilerTimer && - enableProfilerNestedUpdatePhase - ) { - resetNestedUpdateFlag(); - } - - // Since we know we're in a React event, we can clear the current - // event time. The next update will compute a new event time. - currentEventTime = NoTimestamp; - currentEventWipLanes = NoLanes; - currentEventPendingLanes = NoLanes; - - invariant( - (executionContext & - (RenderContext | - CommitContext)) === - NoContext, - 'Should not already be working.', - ); - - // Flush any pending passive effects before deciding which lanes to work on, - // in case they schedule additional work. - const originalCallbackNode = - root.callbackNode; - const didFlushPassiveEffects = flushPassiveEffects(); - if ( - didFlushPassiveEffects - ) { - // Something in the passive effect phase may have canceled the current task. - // Check if the task node for this root was changed. - if ( - root.callbackNode !== - originalCallbackNode - ) { - // The current task was canceled. Exit. We don't need to call - // `ensureRootIsScheduled` because the check above implies either that - // there's a new task, or that there's no remaining work on this root. - return null; - } else { - // Current task was not canceled. Continue. - } - } - - // Determine the next expiration time to work on, using the fields stored - // on the root. - let lanes = getNextLanes( - root, - root === - workInProgressRoot - ? workInProgressRootRenderLanes - : NoLanes, - ); - if ( - lanes === NoLanes - ) { - // Defensive coding. This is never expected to happen. - return null; - } - - // TODO: We only check `didTimeout` defensively, to account for a Scheduler - // bug we're still investigating. Once the bug in Scheduler is fixed, - // we can remove this, since we track expiration ourselves. - if ( - enableSchedulerTimeoutInWorkLoop && - didTimeout - ) { - // Something expired. Flush synchronously until there's no expired - // work left. - markRootExpired( - root, - lanes, - ); - // This will schedule a synchronous callback. - ensureRootIsScheduled( - root, - now(), - ); - return null; - } - - let exitStatus = renderRootConcurrent( - root, - lanes, - ); - - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes, - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // So we'll throw out the current work and restart. - prepareFreshStack( - root, - NoLanes, - ); - } else if ( - exitStatus !== - RootIncomplete - ) { - if ( - exitStatus === - RootErrored - ) { - executionContext |= RetryAfterError; - - // If an error occurred during hydration, - // discard server response and fall back to client side render. - if (root.hydrate) { - root.hydrate = false; - clearContainer( - root.containerInfo, - ); - } - - // If something threw an error, try rendering one more time. We'll render - // synchronously to block concurrent data mutations, and we'll includes - // all pending updates are included. If it still fails after the second - // attempt, we'll give up and commit the resulting tree. - lanes = getLanesToRetrySynchronouslyOnError( - root, - ); - if ( - lanes !== NoLanes - ) { - exitStatus = renderRootSync( - root, - lanes, - ); - } - } - - if ( - exitStatus === - RootFatalErrored - ) { - const fatalError = workInProgressRootFatalError; - prepareFreshStack( - root, - NoLanes, - ); - markRootSuspended( - root, - lanes, - ); - ensureRootIsScheduled( - root, - now(), - ); - throw fatalError; - } - - // We now have a consistent tree. The next step is either to commit it, - // or, if something suspended, wait to commit it after a timeout. - const finishedWork: Fiber = (root - .current - .alternate: any); - root.finishedWork = finishedWork; - root.finishedLanes = lanes; - finishConcurrentRender( - root, - exitStatus, - lanes, - ); - } - - ensureRootIsScheduled( - root, - now(), - ); - if ( - root.callbackNode === - originalCallbackNode - ) { - // The task node scheduled for this root is the same one that's - // currently executed. Need to return a continuation. - return performConcurrentWorkOnRoot.bind( - null, - root, - ); - } - return null; - } + if (enableProfilerTimer && enableProfilerNestedUpdatePhase) { + resetNestedUpdateFlag(); + } + + // Since we know we're in a React event, we can clear the current + // event time. The next update will compute a new event time. + currentEventTime = NoTimestamp; + currentEventWipLanes = NoLanes; + currentEventPendingLanes = NoLanes; + + invariant( + (executionContext & (RenderContext | CommitContext)) === NoContext, + 'Should not already be working.', + ); + + // Flush any pending passive effects before deciding which lanes to work on, + // in case they schedule additional work. + const originalCallbackNode = root.callbackNode; + const didFlushPassiveEffects = flushPassiveEffects(); + if (didFlushPassiveEffects) { + // Something in the passive effect phase may have canceled the current task. + // Check if the task node for this root was changed. + if (root.callbackNode !== originalCallbackNode) { + // The current task was canceled. Exit. We don't need to call + // `ensureRootIsScheduled` because the check above implies either that + // there's a new task, or that there's no remaining work on this root. + return null; + } else { + // Current task was not canceled. Continue. + } + } + + // Determine the next expiration time to work on, using the fields stored + // on the root. + let lanes = getNextLanes( + root, + root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes, + ); + if (lanes === NoLanes) { + // Defensive coding. This is never expected to happen. + return null; + } + + // TODO: We only check `didTimeout` defensively, to account for a Scheduler + // bug we're still investigating. Once the bug in Scheduler is fixed, + // we can remove this, since we track expiration ourselves. + if (!disableSchedulerTimeoutInWorkLoop && didTimeout) { + // Something expired. Flush synchronously until there's no expired + // work left. + markRootExpired(root, lanes); + // This will schedule a synchronous callback. + ensureRootIsScheduled(root, now()); + return null; + } + + let exitStatus = renderRootConcurrent(root, lanes); + + if ( + includesSomeLane( + workInProgressRootIncludedLanes, + workInProgressRootUpdatedLanes, + ) + ) { + // The render included lanes that were updated during the render phase. + // For example, when unhiding a hidden tree, we include all the lanes + // that were previously skipped when the tree was hidden. That set of + // lanes is a superset of the lanes we started rendering with. + // + // So we'll throw out the current work and restart. + prepareFreshStack(root, NoLanes); + } else if (exitStatus !== RootIncomplete) { + if (exitStatus === RootErrored) { + executionContext |= RetryAfterError; + + // If an error occurred during hydration, + // discard server response and fall back to client side render. + if (root.hydrate) { + root.hydrate = false; + clearContainer(root.containerInfo); + } + + // If something threw an error, try rendering one more time. We'll render + // synchronously to block concurrent data mutations, and we'll includes + // all pending updates are included. If it still fails after the second + // attempt, we'll give up and commit the resulting tree. + lanes = getLanesToRetrySynchronouslyOnError(root); + if (lanes !== NoLanes) { + exitStatus = renderRootSync(root, lanes); + } + } + + if (exitStatus === RootFatalErrored) { + const fatalError = workInProgressRootFatalError; + prepareFreshStack(root, NoLanes); + markRootSuspended(root, lanes); + ensureRootIsScheduled(root, now()); + throw fatalError; + } + + // We now have a consistent tree. The next step is either to commit it, + // or, if something suspended, wait to commit it after a timeout. + const finishedWork: Fiber = (root.current.alternate: any); + root.finishedWork = finishedWork; + root.finishedLanes = lanes; + finishConcurrentRender(root, exitStatus, lanes); + } + + ensureRootIsScheduled(root, now()); + if (root.callbackNode === originalCallbackNode) { + // The task node scheduled for this root is the same one that's + // currently executed. Need to return a continuation. + return performConcurrentWorkOnRoot.bind(null, root); + } + return null; +} function finishConcurrentRender(root, exitStatus, lanes) { switch (exitStatus) { diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index ea1a03377e02c..c3ffb65e96ff2 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -142,4 +142,4 @@ export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; -export const enableSchedulerTimeoutInWorkLoop = false; +export const disableSchedulerTimeoutInWorkLoop = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 88ba86e0f7b56..23c926c65a3fb 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -56,7 +56,7 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; -export const enableSchedulerTimeoutInWorkLoop = false; +export const disableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index d8d01b1e58db0..3ed2d7701c93f 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -55,7 +55,7 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; -export const enableSchedulerTimeoutInWorkLoop = false; +export const disableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 56eb405a4ea07..16e488409e0c4 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -55,7 +55,7 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; -export const enableSchedulerTimeoutInWorkLoop = false; +export const disableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js index 07fa3f20f1eab..84ea8902f60c2 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -55,7 +55,7 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; -export const enableSchedulerTimeoutInWorkLoop = false; +export const disableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 6214dc8a600b6..eb1630fc49bd7 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -55,7 +55,7 @@ export const enableDoubleInvokingEffects = true; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; -export const enableSchedulerTimeoutInWorkLoop = false; +export const disableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js index 36606b8367a08..87133385439f3 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.js @@ -55,7 +55,7 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; -export const enableSchedulerTimeoutInWorkLoop = false; +export const disableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.testing.www.js b/packages/shared/forks/ReactFeatureFlags.testing.www.js index a1211cd565c5f..671f44be02952 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.www.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.www.js @@ -55,7 +55,7 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = false; export const enableRecursiveCommitTraversal = false; -export const enableSchedulerTimeoutInWorkLoop = false; +export const disableSchedulerTimeoutInWorkLoop = false; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index 1937d94df8ddc..cf0ca5ae54393 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -53,4 +53,4 @@ export const enableDoubleInvokingEffects = false; export const enableUseRefAccessWarning = __VARIANT__; export const enableProfilerNestedUpdateScheduledHook = __VARIANT__; -export const enableSchedulerTimeoutInWorkLoop = __VARIANT__; +export const disableSchedulerTimeoutInWorkLoop = __VARIANT__; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index fb30b645cdd7b..8b2bda551339e 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -15,22 +15,22 @@ import typeof * as DynamicFeatureFlags from './ReactFeatureFlags.www-dynamic'; const dynamicFeatureFlags: DynamicFeatureFlags = require('ReactFeatureFlags'); export const { - debugRenderPhaseSideEffectsForStrictMode, - disableInputAttributeSyncing, - enableTrustedTypesIntegration, - disableSchedulerTimeoutBasedOnReactExpirationTime, - warnAboutSpreadingKeyToJSX, - replayFailedUnitOfWorkWithInvokeGuardedCallback, - enableFilterEmptyStringAttributesDOM, - enableLegacyFBSupport, - deferRenderPhaseUpdateToNextBatch, - decoupleUpdatePriorityFromScheduler, - enableDebugTracing, - enableDoubleInvokingEffects, - enableUseRefAccessWarning, - disableNativeComponentFrames, - enableSchedulerTimeoutInWorkLoop, - } = dynamicFeatureFlags; + debugRenderPhaseSideEffectsForStrictMode, + disableInputAttributeSyncing, + enableTrustedTypesIntegration, + disableSchedulerTimeoutBasedOnReactExpirationTime, + warnAboutSpreadingKeyToJSX, + replayFailedUnitOfWorkWithInvokeGuardedCallback, + enableFilterEmptyStringAttributesDOM, + enableLegacyFBSupport, + deferRenderPhaseUpdateToNextBatch, + decoupleUpdatePriorityFromScheduler, + enableDebugTracing, + enableDoubleInvokingEffects, + enableUseRefAccessWarning, + disableNativeComponentFrames, + disableSchedulerTimeoutInWorkLoop, +} = dynamicFeatureFlags; // On WWW, __EXPERIMENTAL__ is used for a new modern build. // It's not used anywhere in production yet.