Add feature flag to disable yielding (#15119)
Sebastian Markbåge committed
Mar 15, 2019 at 15:54 UTC
4162f6026c2f560f286e7853f4929cd5e0135bdd
9 files changed
+68
-2
packages/react-dom/src/__tests__/ReactDOMFiberAsync-test.internal.js
+52
@@ -10,6 +10,7 @@
10
'use strict';
11
12
const React = require('react');
13
+const Fragment = React.Fragment;
14
let ReactFeatureFlags = require('shared/ReactFeatureFlags');
15
16
let ReactDOM;
@@ -659,4 +660,55 @@ describe('ReactDOMFiberAsync', () => {
660
expect(formSubmitted).toBe(true);
661
});
662
});
663
+
664
+ describe('Disable yielding', () => {
665
+ beforeEach(() => {
666
+ jest.resetModules();
667
+ ReactFeatureFlags = require('shared/ReactFeatureFlags');
668
+ ReactFeatureFlags.disableYielding = true;
669
+ ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;
670
+ ReactDOM = require('react-dom');
671
+ Scheduler = require('scheduler');
672
+ });
673
+
674
+ it('wont yield during a render if yielding is disabled', () => {
675
+ class A extends React.Component {
676
+ render() {
677
+ Scheduler.yieldValue('A');
678
+ return <div>{this.props.children}</div>;
679
+ }
680
+ }
681
+
682
+ class B extends React.Component {
683
+ render() {
684
+ Scheduler.yieldValue('B');
685
+ return <div>{this.props.children}</div>;
686
+ }
687
+ }
688
+
689
+ class C extends React.Component {
690
+ render() {
691
+ Scheduler.yieldValue('C');
692
+ return <div>{this.props.children}</div>;
693
+ }
694
+ }
695
+
696
+ let root = ReactDOM.unstable_createRoot(container);
697
+
698
+ root.render(
699
+ <Fragment>
700
+ <A />
701
+ <B />
702
+ <C />
703
+ </Fragment>,
704
+ );
705
+
706
+ expect(Scheduler).toHaveYielded([]);
707
+
708
+ Scheduler.unstable_flushNumberOfYields(2);
709
+ // Even though we just flushed two yields, we should have rendered
710
+ // everything without yielding when the flag is on.
711
+ expect(Scheduler).toHaveYielded(['A', 'B', 'C']);
712
+ });
713
+ });
714
});
packages/react-reconciler/src/ReactFiberScheduler.js
+7
-2
@@ -63,6 +63,7 @@ import {
63
replayFailedUnitOfWorkWithInvokeGuardedCallback,
64
warnAboutDeprecatedLifecycles,
65
enableSuspenseServerRenderer,
66
+ disableYielding,
67
} from 'shared/ReactFeatureFlags';
68
import getComponentName from 'shared/getComponentName';
69
import invariant from 'shared/invariant';
@@ -2019,7 +2020,7 @@ function onSuspend(
2020
msUntilTimeout: number,
2021
): void {
2022
root.expirationTime = rootExpirationTime;
2022
- if (msUntilTimeout === 0 && !shouldYield()) {
2023
+ if (msUntilTimeout === 0 && (disableYielding || !shouldYield())) {
2024
// Don't wait an additional tick. Commit the tree immediately.
2025
root.pendingCommitExpirationTime = suspendedExpirationTime;
2026
root.finishedWork = finishedWork;
@@ -2233,7 +2234,11 @@ function performAsyncWork(didTimeout) {
2234
} while (root !== firstScheduledRoot);
2235
}
2236
}
2236
- performWork(NoWork, true);
2237
+ let isYieldy = true;
2238
+ if (disableYielding) {
2239
+ isYieldy = false;
2240
+ }
2241
+ performWork(NoWork, isYieldy);
2242
}
2243
2244
function performSyncWork() {
packages/shared/ReactFeatureFlags.js
+3
@@ -45,6 +45,9 @@ export function addUserTimingListener() {
45
// Disable javascript: URL strings in href for XSS protection.
46
export const disableJavaScriptURLs = false;
47
48
+// Disables yielding during render in Concurrent Mode. Used for debugging only.
49
+export const disableYielding = false;
50
+
51
// React Fire: prevent the value and checked attributes from syncing
52
// with their related DOM properties
53
export const disableInputAttributeSyncing = false;
packages/shared/forks/ReactFeatureFlags.native-fb.js
+1
@@ -25,6 +25,7 @@ export const warnAboutShorthandPropertyCollision = false;
25
export const enableSchedulerDebugging = false;
26
export const debugRenderPhaseSideEffectsForStrictMode = true;
27
export const disableJavaScriptURLs = false;
28
+export const disableYielding = false;
29
export const disableInputAttributeSyncing = false;
30
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
31
export const warnAboutDeprecatedLifecycles = true;
packages/shared/forks/ReactFeatureFlags.native-oss.js
+1
@@ -21,6 +21,7 @@ export const enableProfilerTimer = __PROFILE__;
21
export const enableSchedulerTracing = __PROFILE__;
22
export const enableSuspenseServerRenderer = false;
23
export const disableJavaScriptURLs = false;
24
+export const disableYielding = false;
25
export const disableInputAttributeSyncing = false;
26
export const enableStableConcurrentModeAPIs = false;
27
export const warnAboutShorthandPropertyCollision = false;
packages/shared/forks/ReactFeatureFlags.persistent.js
+1
@@ -21,6 +21,7 @@ export const enableProfilerTimer = __PROFILE__;
21
export const enableSchedulerTracing = __PROFILE__;
22
export const enableSuspenseServerRenderer = false;
23
export const disableJavaScriptURLs = false;
24
+export const disableYielding = false;
25
export const disableInputAttributeSyncing = false;
26
export const enableStableConcurrentModeAPIs = false;
27
export const warnAboutShorthandPropertyCollision = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
+1
@@ -21,6 +21,7 @@ export const enableProfilerTimer = false;
21
export const enableSchedulerTracing = false;
22
export const enableSuspenseServerRenderer = false;
23
export const disableJavaScriptURLs = false;
24
+export const disableYielding = false;
25
export const disableInputAttributeSyncing = false;
26
export const enableStableConcurrentModeAPIs = false;
27
export const warnAboutShorthandPropertyCollision = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+1
@@ -24,6 +24,7 @@ export const enableStableConcurrentModeAPIs = false;
24
export const enableSchedulerDebugging = false;
25
export const warnAboutDeprecatedSetNativeProps = false;
26
export const disableJavaScriptURLs = false;
27
+export const disableYielding = false;
28
export const enableEventAPI = true;
29
30
// Only used in www builds.
packages/shared/forks/ReactFeatureFlags.www.js
+1
@@ -17,6 +17,7 @@ export const {
17
replayFailedUnitOfWorkWithInvokeGuardedCallback,
18
warnAboutDeprecatedLifecycles,
19
disableJavaScriptURLs,
20
+ disableYielding,
21
disableInputAttributeSyncing,
22
warnAboutShorthandPropertyCollision,
23
warnAboutDeprecatedSetNativeProps,