Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions packages/react-reconciler/src/ReactFiberWorkLoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
enableSiblingPrerendering,
enableComponentPerformanceTrack,
enableYieldingBeforePassive,
enableThrottledScheduling,
} from 'shared/ReactFeatureFlags';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import is from 'shared/objectIs';
Expand Down Expand Up @@ -2610,8 +2611,10 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
// can't trust the result of `shouldYield`, because the host I/O is
// likely mocked.
workLoopSync();
} else if (enableThrottledScheduling) {
workLoopConcurrent(includesNonIdleWork(lanes));
} else {
workLoopConcurrent();
workLoopConcurrentByScheduler();
}
break;
} catch (thrownValue) {
Expand Down Expand Up @@ -2650,10 +2653,27 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {
}

/** @noinline */
function workLoopConcurrent() {
function workLoopConcurrent(nonIdle: boolean) {
// We yield every other "frame" when rendering Transition or Retries. Those are blocking
// revealing new content. The purpose of this yield is not to avoid the overhead of yielding,
// which is very low, but rather to intentionally block any frequently occuring other main
// thread work like animations from starving our work. In other words, the purpose of this
// is to reduce the framerate of animations to 30 frames per second.
// For Idle work we yield every 5ms to keep animations going smooth.
if (workInProgress !== null) {
const yieldAfter = now() + (nonIdle ? 25 : 5);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is now snapshotted deeper, it doesn't account for the overhead in React to get to this point. We could move this outside but also that overhead should ideally be pretty small, fixed and known.

do {
// $FlowFixMe[incompatible-call] flow doesn't know that now() is side-effect free
performUnitOfWork(workInProgress);
} while (workInProgress !== null && now() < yieldAfter);
}
}

/** @noinline */
function workLoopConcurrentByScheduler() {
// Perform work until Scheduler asks us to yield
while (workInProgress !== null && !shouldYield()) {
// $FlowFixMe[incompatible-call] found when upgrading Flow
// $FlowFixMe[incompatible-call] flow doesn't know that shouldYield() is side-effect free
performUnitOfWork(workInProgress);
}
}
Expand Down
3 changes: 3 additions & 0 deletions packages/shared/ReactFeatureFlags.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ export const enableLegacyFBSupport = false;
// Fix gated tests that fail with this flag enabled before turning it back on.
export const enableYieldingBeforePassive = false;

// Experiment to intentionally yield less to block high framerate animations.
export const enableThrottledScheduling = false;

export const enableLegacyCache = __EXPERIMENTAL__;

export const enableAsyncIterableChildren = __EXPERIMENTAL__;
Expand Down
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.native-fb.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export const syncLaneExpirationMs = 250;
export const transitionLaneExpirationMs = 5000;
export const enableHydrationLaneScheduling = true;
export const enableYieldingBeforePassive = false;
export const enableThrottledScheduling = false;

// Flow magic to verify the exports of this file match the original version.
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
2 changes: 2 additions & 0 deletions packages/shared/forks/ReactFeatureFlags.native-oss.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ export const enableHydrationLaneScheduling = true;

export const enableYieldingBeforePassive = false;

export const enableThrottledScheduling = false;

// Profiling Only
export const enableProfilerTimer = __PROFILE__;
export const enableProfilerCommitHooks = __PROFILE__;
Expand Down
2 changes: 2 additions & 0 deletions packages/shared/forks/ReactFeatureFlags.test-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ export const enableUseResourceEffectHook = false;

export const enableYieldingBeforePassive = true;

export const enableThrottledScheduling = false;

// TODO: This must be in sync with the main ReactFeatureFlags file because
// the Test Renderer's value must be the same as the one used by the
// react package.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const enableSiblingPrerendering = true;
export const enableUseResourceEffectHook = true;
export const enableHydrationLaneScheduling = true;
export const enableYieldingBeforePassive = false;
export const enableThrottledScheduling = false;

// Flow magic to verify the exports of this file match the original version.
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
2 changes: 2 additions & 0 deletions packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,7 @@ export const enableHydrationLaneScheduling = true;

export const enableYieldingBeforePassive = false;

export const enableThrottledScheduling = false;

// Flow magic to verify the exports of this file match the original version.
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
2 changes: 2 additions & 0 deletions packages/shared/forks/ReactFeatureFlags.www.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ export const enableLegacyFBSupport = true;

export const enableYieldingBeforePassive = false;

export const enableThrottledScheduling = false;

export const enableHydrationLaneScheduling = true;

export const enableComponentPerformanceTrack = false;
Expand Down
Loading