Skip to content

Commit 4162f60

Browse files
authored
Add feature flag to disable yielding (#15119)
1 parent 8d60bd4 commit 4162f60

9 files changed

+68
-2
lines changed

packages/react-dom/src/__tests__/ReactDOMFiberAsync-test.internal.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'use strict';
1111

1212
const React = require('react');
13+
const Fragment = React.Fragment;
1314
let ReactFeatureFlags = require('shared/ReactFeatureFlags');
1415

1516
let ReactDOM;
@@ -659,4 +660,55 @@ describe('ReactDOMFiberAsync', () => {
659660
expect(formSubmitted).toBe(true);
660661
});
661662
});
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+
});
662714
});

packages/react-reconciler/src/ReactFiberScheduler.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import {
6363
replayFailedUnitOfWorkWithInvokeGuardedCallback,
6464
warnAboutDeprecatedLifecycles,
6565
enableSuspenseServerRenderer,
66+
disableYielding,
6667
} from 'shared/ReactFeatureFlags';
6768
import getComponentName from 'shared/getComponentName';
6869
import invariant from 'shared/invariant';
@@ -2019,7 +2020,7 @@ function onSuspend(
20192020
msUntilTimeout: number,
20202021
): void {
20212022
root.expirationTime = rootExpirationTime;
2022-
if (msUntilTimeout === 0 && !shouldYield()) {
2023+
if (msUntilTimeout === 0 && (disableYielding || !shouldYield())) {
20232024
// Don't wait an additional tick. Commit the tree immediately.
20242025
root.pendingCommitExpirationTime = suspendedExpirationTime;
20252026
root.finishedWork = finishedWork;
@@ -2233,7 +2234,11 @@ function performAsyncWork(didTimeout) {
22332234
} while (root !== firstScheduledRoot);
22342235
}
22352236
}
2236-
performWork(NoWork, true);
2237+
let isYieldy = true;
2238+
if (disableYielding) {
2239+
isYieldy = false;
2240+
}
2241+
performWork(NoWork, isYieldy);
22372242
}
22382243

22392244
function performSyncWork() {

packages/shared/ReactFeatureFlags.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ export function addUserTimingListener() {
4545
// Disable javascript: URL strings in href for XSS protection.
4646
export const disableJavaScriptURLs = false;
4747

48+
// Disables yielding during render in Concurrent Mode. Used for debugging only.
49+
export const disableYielding = false;
50+
4851
// React Fire: prevent the value and checked attributes from syncing
4952
// with their related DOM properties
5053
export const disableInputAttributeSyncing = false;

packages/shared/forks/ReactFeatureFlags.native-fb.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const warnAboutShorthandPropertyCollision = false;
2525
export const enableSchedulerDebugging = false;
2626
export const debugRenderPhaseSideEffectsForStrictMode = true;
2727
export const disableJavaScriptURLs = false;
28+
export const disableYielding = false;
2829
export const disableInputAttributeSyncing = false;
2930
export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
3031
export const warnAboutDeprecatedLifecycles = true;

packages/shared/forks/ReactFeatureFlags.native-oss.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const enableProfilerTimer = __PROFILE__;
2121
export const enableSchedulerTracing = __PROFILE__;
2222
export const enableSuspenseServerRenderer = false;
2323
export const disableJavaScriptURLs = false;
24+
export const disableYielding = false;
2425
export const disableInputAttributeSyncing = false;
2526
export const enableStableConcurrentModeAPIs = false;
2627
export const warnAboutShorthandPropertyCollision = false;

packages/shared/forks/ReactFeatureFlags.persistent.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const enableProfilerTimer = __PROFILE__;
2121
export const enableSchedulerTracing = __PROFILE__;
2222
export const enableSuspenseServerRenderer = false;
2323
export const disableJavaScriptURLs = false;
24+
export const disableYielding = false;
2425
export const disableInputAttributeSyncing = false;
2526
export const enableStableConcurrentModeAPIs = false;
2627
export const warnAboutShorthandPropertyCollision = false;

packages/shared/forks/ReactFeatureFlags.test-renderer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const enableProfilerTimer = false;
2121
export const enableSchedulerTracing = false;
2222
export const enableSuspenseServerRenderer = false;
2323
export const disableJavaScriptURLs = false;
24+
export const disableYielding = false;
2425
export const disableInputAttributeSyncing = false;
2526
export const enableStableConcurrentModeAPIs = false;
2627
export const warnAboutShorthandPropertyCollision = false;

packages/shared/forks/ReactFeatureFlags.test-renderer.www.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export const enableStableConcurrentModeAPIs = false;
2424
export const enableSchedulerDebugging = false;
2525
export const warnAboutDeprecatedSetNativeProps = false;
2626
export const disableJavaScriptURLs = false;
27+
export const disableYielding = false;
2728
export const enableEventAPI = true;
2829

2930
// Only used in www builds.

packages/shared/forks/ReactFeatureFlags.www.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const {
1717
replayFailedUnitOfWorkWithInvokeGuardedCallback,
1818
warnAboutDeprecatedLifecycles,
1919
disableJavaScriptURLs,
20+
disableYielding,
2021
disableInputAttributeSyncing,
2122
warnAboutShorthandPropertyCollision,
2223
warnAboutDeprecatedSetNativeProps,

0 commit comments

Comments
 (0)