Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decouple update priority tracking from Scheduler package #19121

Merged
merged 36 commits into from
Jul 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
dc66f1b
Initial currentLanePriority implementation
rickhanlonii Jun 12, 2020
dd82bcd
Minor updates from review
rickhanlonii Jun 12, 2020
4404ed2
Fix typos and enable flag
rickhanlonii Jun 16, 2020
a029969
Fix feature flags and lint
rickhanlonii Jun 16, 2020
815c4ed
Fix simple event tests by switching to withSuspenseConfig
rickhanlonii Jun 19, 2020
c454bda
Don't lower the priority of setPending in startTransition below Input…
rickhanlonii Jun 19, 2020
6fe9d23
Move currentUpdateLanePriority in commit root into the first effect b…
rickhanlonii Jun 19, 2020
7d5c251
Refactor requestUpdateLane to log for priority mismatches
rickhanlonii Jun 19, 2020
79fdca3
Fix four tests by adding ReactDOM.unstable_runWithPriority
rickhanlonii Jun 20, 2020
a238e2f
Fix partial hydration when using update lane priority
rickhanlonii Jun 20, 2020
2dcd2aa
Fix partial hydration when using update lane priority
rickhanlonii Jun 20, 2020
db5f479
Rename feature flag and only log for now
rickhanlonii Jun 26, 2020
fbbddcf
Move unstable_runWithPriority to ReactFiberReconciler
rickhanlonii Jun 26, 2020
93eca31
Add unstable_runWithPriority to ReactNoopPersistent too
rickhanlonii Jun 26, 2020
ce0c4a6
Bug fixes and performance improvements
rickhanlonii Jun 26, 2020
6e7fbbe
Remove higherLanePriority from ReactDOMEventReplaying.js
rickhanlonii Jun 30, 2020
a2445c2
Change warning implementation and startTransition update lane priority
rickhanlonii Jun 30, 2020
f3cb0d8
Inject reconciler functions to avoid importing src/
rickhanlonii Jun 30, 2020
866c5ba
Initial currentLanePriority implementation
rickhanlonii Jun 12, 2020
d132425
Minor updates from review
rickhanlonii Jun 12, 2020
0844f04
Fix typos and enable flag
rickhanlonii Jun 16, 2020
e317e3a
Fix feature flags and lint
rickhanlonii Jun 16, 2020
9f472fb
Fix simple event tests by switching to withSuspenseConfig
rickhanlonii Jun 19, 2020
8f58f02
Don't lower the priority of setPending in startTransition below Input…
rickhanlonii Jun 19, 2020
1930096
Move currentUpdateLanePriority in commit root into the first effect b…
rickhanlonii Jun 19, 2020
6b500da
Refactor requestUpdateLane to log for priority mismatches
rickhanlonii Jun 19, 2020
863ce17
Fix four tests by adding ReactDOM.unstable_runWithPriority
rickhanlonii Jun 20, 2020
27adc13
Fix partial hydration when using update lane priority
rickhanlonii Jun 20, 2020
c6c760d
Fix partial hydration when using update lane priority
rickhanlonii Jun 20, 2020
28a889f
Rename feature flag and only log for now
rickhanlonii Jun 26, 2020
9c71654
Move unstable_runWithPriority to ReactFiberReconciler
rickhanlonii Jun 26, 2020
5802d55
Bug fixes and performance improvements
rickhanlonii Jun 26, 2020
0d9812c
Remove higherLanePriority from ReactDOMEventReplaying.js
rickhanlonii Jun 30, 2020
383eb73
Change warning implementation and startTransition update lane priority
rickhanlonii Jun 30, 2020
23eb05a
Inject reconciler functions to avoid importing src/
rickhanlonii Jun 30, 2020
4294152
Fixes from bad rebase
rickhanlonii Jul 6, 2020
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
1 change: 1 addition & 0 deletions packages/react-dom/index.classic.fb.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export {
createBlockingRoot as unstable_createBlockingRoot,
unstable_flushControlled,
unstable_scheduleHydration,
unstable_runWithPriority,
unstable_renderSubtreeIntoContainer,
unstable_createPortal,
unstable_createEventHandle,
Expand Down
2 changes: 2 additions & 0 deletions packages/react-dom/index.experimental.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export {
createBlockingRoot as unstable_createBlockingRoot,
unstable_flushControlled,
unstable_scheduleHydration,
// DO NOT USE: Temporarily exposing this to migrate off of Scheduler.runWithPriority.
unstable_runWithPriority,
// Disabled behind disableUnstableRenderSubtreeIntoContainer
unstable_renderSubtreeIntoContainer,
// Disabled behind disableUnstableCreatePortal
Expand Down
1 change: 1 addition & 0 deletions packages/react-dom/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export {
createBlockingRoot as unstable_createBlockingRoot,
unstable_flushControlled,
unstable_scheduleHydration,
unstable_runWithPriority,
unstable_renderSubtreeIntoContainer,
unstable_createPortal,
unstable_createEventHandle,
Expand Down
1 change: 1 addition & 0 deletions packages/react-dom/index.modern.fb.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export {
createBlockingRoot as unstable_createBlockingRoot,
unstable_flushControlled,
unstable_scheduleHydration,
unstable_runWithPriority,
unstable_createEventHandle,
unstable_isNewReconciler,
} from './src/client/ReactDOM';
9 changes: 9 additions & 0 deletions packages/react-dom/src/client/ReactDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import {
attemptUserBlockingHydration,
attemptContinuousHydration,
attemptHydrationAtCurrentPriority,
runWithPriority,
getCurrentUpdatePriority,
} from 'react-reconciler/src/ReactFiberReconciler';
import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal';
import {canUseDOM} from 'shared/ExecutionEnvironment';
Expand All @@ -58,6 +60,8 @@ import {
setAttemptContinuousHydration,
setAttemptHydrationAtCurrentPriority,
queueExplicitHydrationTarget,
setGetCurrentUpdatePriority,
setAttemptHydrationAtPriority,
} from '../events/ReactDOMEventReplaying';
import {setBatchingImplementation} from '../events/ReactDOMUpdateBatching';
import {
Expand All @@ -70,6 +74,8 @@ setAttemptSynchronousHydration(attemptSynchronousHydration);
setAttemptUserBlockingHydration(attemptUserBlockingHydration);
setAttemptContinuousHydration(attemptContinuousHydration);
setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority);
setGetCurrentUpdatePriority(getCurrentUpdatePriority);
setAttemptHydrationAtPriority(runWithPriority);

let didWarnAboutUnstableCreatePortal = false;
let didWarnAboutUnstableRenderSubtreeIntoContainer = false;
Expand Down Expand Up @@ -205,6 +211,9 @@ export {
unstable_createPortal,
// enableCreateEventHandleAPI
createEventHandle as unstable_createEventHandle,
// TODO: Remove this once callers migrate to alternatives.
// This should only be used by React internals.
runWithPriority as unstable_runWithPriority,
};

const foundDevTools = injectIntoDevTools({
Expand Down
38 changes: 32 additions & 6 deletions packages/react-dom/src/events/ReactDOMEventReplaying.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
import type {DOMTopLevelEventType} from '../events/TopLevelEventTypes';
import type {ElementListenerMap} from '../client/ReactDOMComponentTree';
import type {EventSystemFlags} from './EventSystemFlags';
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
import type {
FiberRoot,
ReactPriorityLevel,
} from 'react-reconciler/src/ReactInternalTypes';

import {
enableDeprecatedFlareAPI,
Expand Down Expand Up @@ -64,6 +67,23 @@ export function setAttemptHydrationAtCurrentPriority(
attemptHydrationAtCurrentPriority = fn;
}

let getCurrentUpdatePriority: () => ReactPriorityLevel;

export function setGetCurrentUpdatePriority(fn: () => ReactPriorityLevel) {
getCurrentUpdatePriority = fn;
}

let attemptHydrationAtPriority: <T>(
priority: ReactPriorityLevel,
fn: () => T,
) => T;

export function setAttemptHydrationAtPriority(
fn: <T>(priority: ReactPriorityLevel, fn: () => T) => T,
) {
attemptHydrationAtPriority = fn;
}

// TODO: Upgrade this definition once we're on a newer version of Flow that
// has this definition built-in.
type PointerEvent = Event & {
Expand Down Expand Up @@ -147,6 +167,7 @@ type QueuedHydrationTarget = {|
blockedOn: null | Container | SuspenseInstance,
target: Node,
priority: number,
lanePriority: ReactPriorityLevel,
|};
const queuedExplicitHydrationTargets: Array<QueuedHydrationTarget> = [];

Expand Down Expand Up @@ -508,9 +529,12 @@ function attemptExplicitHydrationTarget(
// We're blocked on hydrating this boundary.
// Increase its priority.
queuedTarget.blockedOn = instance;
runWithPriority(queuedTarget.priority, () => {
attemptHydrationAtCurrentPriority(nearestMounted);
attemptHydrationAtPriority(queuedTarget.lanePriority, () => {
runWithPriority(queuedTarget.priority, () => {
attemptHydrationAtCurrentPriority(nearestMounted);
});
});

return;
}
} else if (tag === HostRoot) {
Expand All @@ -529,15 +553,17 @@ function attemptExplicitHydrationTarget(

export function queueExplicitHydrationTarget(target: Node): void {
if (enableSelectiveHydration) {
const priority = getCurrentPriorityLevel();
const schedulerPriority = getCurrentPriorityLevel();
const updateLanePriority = getCurrentUpdatePriority();
const queuedTarget: QueuedHydrationTarget = {
blockedOn: null,
target: target,
priority: priority,
priority: schedulerPriority,
lanePriority: updateLanePriority,
rickhanlonii marked this conversation as resolved.
Show resolved Hide resolved
};
let i = 0;
for (; i < queuedExplicitHydrationTargets.length; i++) {
if (priority <= queuedExplicitHydrationTargets[i].priority) {
if (schedulerPriority <= queuedExplicitHydrationTargets[i].priority) {
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ describe('SimpleEventPlugin', function() {
describe('interactive events, in concurrent mode', () => {
beforeEach(() => {
jest.resetModules();

React = require('react');
ReactDOM = require('react-dom');
Scheduler = require('scheduler');
});
Expand Down Expand Up @@ -377,11 +379,14 @@ describe('SimpleEventPlugin', function() {
<button
ref={el => (button = el)}
onClick={() => {
Scheduler.unstable_next(() => {
this.setState(state => ({
lowPriCount: state.lowPriCount + 1,
}));
});
React.unstable_withSuspenseConfig(
() => {
this.setState(state => ({
lowPriCount: state.lowPriCount + 1,
}));
},
{timeoutMs: 5000},
);
}}>
{text}
</button>
Expand Down
3 changes: 3 additions & 0 deletions packages/react-noop-renderer/src/ReactNoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ export const {
act,
dumpTree,
getRoot,
// TODO: Remove this once callers migrate to alternatives.
// This should only be used by React internals.
unstable_runWithPriority,
} = createReactNoop(
ReactFiberReconciler, // reconciler
true, // useMutation
Expand Down
3 changes: 3 additions & 0 deletions packages/react-noop-renderer/src/ReactNoopPersistent.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ export const {
act,
dumpTree,
getRoot,
// TODO: Remove this once callers migrate to alternatives.
// This should only be used by React internals.
unstable_runWithPriority,
} = createReactNoop(
ReactFiberReconciler, // reconciler
false, // useMutation
Expand Down
2 changes: 2 additions & 0 deletions packages/react-noop-renderer/src/createReactNoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,8 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
return Scheduler.unstable_flushExpired();
},

unstable_runWithPriority: NoopRenderer.runWithPriority,

batchedUpdates: NoopRenderer.batchedUpdates,

deferredUpdates: NoopRenderer.deferredUpdates,
Expand Down
14 changes: 14 additions & 0 deletions packages/react-reconciler/src/ReactFiberHooks.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,16 @@ import {NoMode, BlockingMode} from './ReactTypeOfMode';
import {
NoLane,
NoLanes,
InputContinuousLanePriority,
isSubsetOfLanes,
mergeLanes,
removeLanes,
markRootEntangled,
markRootMutableRead,
getCurrentUpdateLanePriority,
setCurrentUpdateLanePriority,
higherLanePriority,
DefaultLanePriority,
} from './ReactFiberLane';
import {readContext} from './ReactFiberNewContext.new';
import {createDeprecatedResponderListener} from './ReactFiberDeprecatedEvents.new';
Expand Down Expand Up @@ -1498,12 +1503,20 @@ function rerenderDeferredValue<T>(

function startTransition(setPending, config, callback) {
const priorityLevel = getCurrentPriorityLevel();
const previousLanePriority = getCurrentUpdateLanePriority();
setCurrentUpdateLanePriority(
higherLanePriority(previousLanePriority, InputContinuousLanePriority),
);
runWithPriority(
priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel,
() => {
setPending(true);
},
);

// If there's no SuspenseConfig set, we'll use the DefaultLanePriority for this transition.
setCurrentUpdateLanePriority(DefaultLanePriority);

runWithPriority(
priorityLevel > NormalPriority ? NormalPriority : priorityLevel,
() => {
Expand All @@ -1513,6 +1526,7 @@ function startTransition(setPending, config, callback) {
setPending(false);
callback();
} finally {
setCurrentUpdateLanePriority(previousLanePriority);
ReactCurrentBatchConfig.suspense = previousConfig;
}
},
Expand Down
14 changes: 14 additions & 0 deletions packages/react-reconciler/src/ReactFiberHooks.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,16 @@ import {NoMode, BlockingMode, DebugTracingMode} from './ReactTypeOfMode';
import {
NoLane,
NoLanes,
InputContinuousLanePriority,
isSubsetOfLanes,
mergeLanes,
removeLanes,
markRootEntangled,
markRootMutableRead,
getCurrentUpdateLanePriority,
setCurrentUpdateLanePriority,
higherLanePriority,
DefaultLanePriority,
} from './ReactFiberLane';
import {readContext} from './ReactFiberNewContext.old';
import {createDeprecatedResponderListener} from './ReactFiberDeprecatedEvents.old';
Expand Down Expand Up @@ -1502,12 +1507,20 @@ function rerenderDeferredValue<T>(

function startTransition(setPending, config, callback) {
const priorityLevel = getCurrentPriorityLevel();
const previousLanePriority = getCurrentUpdateLanePriority();
setCurrentUpdateLanePriority(
higherLanePriority(previousLanePriority, InputContinuousLanePriority),
);
runWithPriority(
priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel,
() => {
setPending(true);
},
);

// If there's no SuspenseConfig set, we'll use the DefaultLanePriority for this transition.
setCurrentUpdateLanePriority(DefaultLanePriority);

runWithPriority(
priorityLevel > NormalPriority ? NormalPriority : priorityLevel,
() => {
Expand All @@ -1517,6 +1530,7 @@ function startTransition(setPending, config, callback) {
setPending(false);
callback();
} finally {
setCurrentUpdateLanePriority(previousLanePriority);
ReactCurrentBatchConfig.suspense = previousConfig;
}
},
Expand Down
21 changes: 19 additions & 2 deletions packages/react-reconciler/src/ReactFiberLane.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ const InputDiscreteHydrationLanePriority: LanePriority = 14;
export const InputDiscreteLanePriority: LanePriority = 13;

const InputContinuousHydrationLanePriority: LanePriority = 12;
const InputContinuousLanePriority: LanePriority = 11;
export const InputContinuousLanePriority: LanePriority = 11;

const DefaultHydrationLanePriority: LanePriority = 10;
const DefaultLanePriority: LanePriority = 9;
export const DefaultLanePriority: LanePriority = 9;

const TransitionShortHydrationLanePriority: LanePriority = 8;
export const TransitionShortLanePriority: LanePriority = 7;
Expand Down Expand Up @@ -120,6 +120,16 @@ export const OffscreenLane: Lane = /* */ 0b1000000000000000000

export const NoTimestamp = -1;

let currentUpdateLanePriority: LanePriority = NoLanePriority;

export function getCurrentUpdateLanePriority(): LanePriority {
return currentUpdateLanePriority;
}

export function setCurrentUpdateLanePriority(newLanePriority: LanePriority) {
currentUpdateLanePriority = newLanePriority;
}

// "Registers" used to "return" multiple values
// Used by getHighestPriorityLanes and getNextLanes:
let return_highestLanePriority: LanePriority = DefaultLanePriority;
Expand Down Expand Up @@ -651,6 +661,13 @@ export function higherPriorityLane(a: Lane, b: Lane) {
return a !== NoLane && a < b ? a : b;
}

export function higherLanePriority(
a: LanePriority,
b: LanePriority,
): LanePriority {
return a !== NoLanePriority && a > b ? a : b;
}

export function createLaneMap<T>(initial: T): LaneMap<T> {
return new Array(TotalLanes).fill(initial);
}
Expand Down
10 changes: 10 additions & 0 deletions packages/react-reconciler/src/ReactFiberReconciler.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ import {
focusWithin as focusWithin_old,
observeVisibleRects as observeVisibleRects_old,
registerMutableSourceForHydration as registerMutableSourceForHydration_old,
runWithPriority as runWithPriority_old,
getCurrentUpdatePriority as getCurrentUpdatePriority_old,
} from './ReactFiberReconciler.old';

import {
Expand Down Expand Up @@ -88,6 +90,8 @@ import {
focusWithin as focusWithin_new,
observeVisibleRects as observeVisibleRects_new,
registerMutableSourceForHydration as registerMutableSourceForHydration_new,
runWithPriority as runWithPriority_new,
getCurrentUpdatePriority as getCurrentUpdatePriority_new,
} from './ReactFiberReconciler.new';

export const createContainer = enableNewReconciler
Expand Down Expand Up @@ -139,6 +143,9 @@ export const attemptContinuousHydration = enableNewReconciler
export const attemptHydrationAtCurrentPriority = enableNewReconciler
? attemptHydrationAtCurrentPriority_new
: attemptHydrationAtCurrentPriority_old;
export const getCurrentUpdatePriority = enableNewReconciler
? getCurrentUpdatePriority_new
: getCurrentUpdatePriority_old;
export const findHostInstance = enableNewReconciler
? findHostInstance_new
: findHostInstance_old;
Expand Down Expand Up @@ -194,3 +201,6 @@ export const observeVisibleRects = enableNewReconciler
export const registerMutableSourceForHydration = enableNewReconciler
? registerMutableSourceForHydration_new
: registerMutableSourceForHydration_old;
export const runWithPriority = enableNewReconciler
? runWithPriority_new
: runWithPriority_old;
Loading