Set current update lane priority for user blocking events (#19342)

* Set current update lane priority for user blocking events

* Update to use LanePriority and not use runWithPriority

* Remove unused imports

* Fix tests, and I missed ReactDOMEventListener

* Fix more tests

* Add try/finally and hardcode lane priorities instead

* Also hard code InputContinuousLanePriority in tests

* Remove un-needed exports

* Comment rollbacks
This commit is contained in:
Ricky
2020-07-17 12:58:44 -04:00
committed by GitHub
parent 4c8c98ab9b
commit faa697f4f9
10 changed files with 106 additions and 104 deletions
+2 -2
View File
@@ -36,7 +36,7 @@ import {
attemptContinuousHydration,
attemptHydrationAtCurrentPriority,
runWithPriority,
getCurrentUpdatePriority,
getCurrentUpdateLanePriority,
} from 'react-reconciler/src/ReactFiberReconciler';
import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal';
import {canUseDOM} from 'shared/ExecutionEnvironment';
@@ -74,7 +74,7 @@ setAttemptSynchronousHydration(attemptSynchronousHydration);
setAttemptUserBlockingHydration(attemptUserBlockingHydration);
setAttemptContinuousHydration(attemptContinuousHydration);
setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority);
setGetCurrentUpdatePriority(getCurrentUpdatePriority);
setGetCurrentUpdatePriority(getCurrentUpdateLanePriority);
setAttemptHydrationAtPriority(runWithPriority);
let didWarnAboutUnstableCreatePortal = false;
@@ -56,6 +56,13 @@ import {
// Intentionally not named imports because Rollup would use dynamic dispatch for
// CommonJS interop named imports.
import * as Scheduler from 'scheduler';
import {
InputContinuousLanePriority,
getCurrentUpdateLanePriority,
setCurrentUpdateLanePriority,
} from 'react-reconciler/src/ReactFiberLane';
const {
unstable_UserBlockingPriority: UserBlockingPriority,
unstable_runWithPriority: runWithPriority,
@@ -101,9 +108,15 @@ const eventResponderContext: ReactDOMResponderContext = {
break;
}
case UserBlockingEvent: {
runWithPriority(UserBlockingPriority, () =>
executeUserEventHandler(eventListener, eventValue),
);
const previousPriority = getCurrentUpdateLanePriority();
try {
setCurrentUpdateLanePriority(InputContinuousLanePriority);
runWithPriority(UserBlockingPriority, () =>
executeUserEventHandler(eventListener, eventValue),
);
} finally {
setCurrentUpdateLanePriority(previousPriority);
}
break;
}
case ContinuousEvent: {
+22 -10
View File
@@ -56,6 +56,11 @@ import {
flushDiscreteUpdatesIfNeeded,
discreteUpdates,
} from './ReactDOMUpdateBatching';
import {
InputContinuousLanePriority,
getCurrentUpdateLanePriority,
setCurrentUpdateLanePriority,
} from 'react-reconciler/src/ReactFiberLane';
const {
unstable_UserBlockingPriority: UserBlockingPriority,
@@ -148,16 +153,23 @@ function dispatchUserBlockingUpdate(
container,
nativeEvent,
) {
runWithPriority(
UserBlockingPriority,
dispatchEvent.bind(
null,
topLevelType,
eventSystemFlags,
container,
nativeEvent,
),
);
// TODO: Double wrapping is necessary while we decouple Scheduler priority.
const previousPriority = getCurrentUpdateLanePriority();
try {
setCurrentUpdateLanePriority(InputContinuousLanePriority);
runWithPriority(
UserBlockingPriority,
dispatchEvent.bind(
null,
topLevelType,
eventSystemFlags,
container,
nativeEvent,
),
);
} finally {
setCurrentUpdateLanePriority(previousPriority);
}
}
export function dispatchEvent(
+7 -12
View File
@@ -12,10 +12,8 @@ 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,
ReactPriorityLevel,
} from 'react-reconciler/src/ReactInternalTypes';
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
import type {LanePriority} from 'react-reconciler/src/ReactFiberLane';
import {
enableDeprecatedFlareAPI,
@@ -67,19 +65,16 @@ export function setAttemptHydrationAtCurrentPriority(
attemptHydrationAtCurrentPriority = fn;
}
let getCurrentUpdatePriority: () => ReactPriorityLevel;
let getCurrentUpdatePriority: () => LanePriority;
export function setGetCurrentUpdatePriority(fn: () => ReactPriorityLevel) {
export function setGetCurrentUpdatePriority(fn: () => LanePriority) {
getCurrentUpdatePriority = fn;
}
let attemptHydrationAtPriority: <T>(
priority: ReactPriorityLevel,
fn: () => T,
) => T;
let attemptHydrationAtPriority: <T>(priority: LanePriority, fn: () => T) => T;
export function setAttemptHydrationAtPriority(
fn: <T>(priority: ReactPriorityLevel, fn: () => T) => T,
fn: <T>(priority: LanePriority, fn: () => T) => T,
) {
attemptHydrationAtPriority = fn;
}
@@ -170,7 +165,7 @@ type QueuedHydrationTarget = {|
blockedOn: null | Container | SuspenseInstance,
target: Node,
priority: number,
lanePriority: ReactPriorityLevel,
lanePriority: LanePriority,
|};
const queuedExplicitHydrationTargets: Array<QueuedHydrationTarget> = [];
+1 -2
View File
@@ -47,8 +47,7 @@ export const {
act,
dumpTree,
getRoot,
// TODO: Remove this once callers migrate to alternatives.
// This should only be used by React internals.
// TODO: Remove this after callers migrate to alternatives.
unstable_runWithPriority,
} = createReactNoop(
ReactFiberReconciler, // reconciler
+5 -6
View File
@@ -51,7 +51,7 @@ import {
observeVisibleRects as observeVisibleRects_old,
registerMutableSourceForHydration as registerMutableSourceForHydration_old,
runWithPriority as runWithPriority_old,
getCurrentUpdatePriority as getCurrentUpdatePriority_old,
getCurrentUpdateLanePriority as getCurrentUpdateLanePriority_old,
} from './ReactFiberReconciler.old';
import {
@@ -91,7 +91,7 @@ import {
observeVisibleRects as observeVisibleRects_new,
registerMutableSourceForHydration as registerMutableSourceForHydration_new,
runWithPriority as runWithPriority_new,
getCurrentUpdatePriority as getCurrentUpdatePriority_new,
getCurrentUpdateLanePriority as getCurrentUpdateLanePriority_new,
} from './ReactFiberReconciler.new';
export const createContainer = enableNewReconciler
@@ -143,9 +143,9 @@ export const attemptContinuousHydration = enableNewReconciler
export const attemptHydrationAtCurrentPriority = enableNewReconciler
? attemptHydrationAtCurrentPriority_new
: attemptHydrationAtCurrentPriority_old;
export const getCurrentUpdatePriority = enableNewReconciler
? getCurrentUpdatePriority_new
: getCurrentUpdatePriority_old;
export const getCurrentUpdateLanePriority = enableNewReconciler
? getCurrentUpdateLanePriority_new
: getCurrentUpdateLanePriority_old;
export const findHostInstance = enableNewReconciler
? findHostInstance_new
: findHostInstance_old;
@@ -197,7 +197,6 @@ export const focusWithin = enableNewReconciler
export const observeVisibleRects = enableNewReconciler
? observeVisibleRects_new
: observeVisibleRects_old;
export const registerMutableSourceForHydration = enableNewReconciler
? registerMutableSourceForHydration_new
: registerMutableSourceForHydration_old;
@@ -7,11 +7,7 @@
* @flow
*/
import type {
Fiber,
ReactPriorityLevel,
SuspenseHydrationCallbacks,
} from './ReactInternalTypes';
import type {Fiber, SuspenseHydrationCallbacks} from './ReactInternalTypes';
import type {FiberRoot} from './ReactInternalTypes';
import type {RootTag} from './ReactRootTags';
import type {
@@ -23,7 +19,7 @@ import type {
import type {RendererInspectionConfig} from './ReactFiberHostConfig';
import {FundamentalComponent} from './ReactWorkTags';
import type {ReactNodeList} from 'shared/ReactTypes';
import type {Lane} from './ReactFiberLane';
import type {Lane, LanePriority} from './ReactFiberLane';
import type {SuspenseState} from './ReactFiberSuspenseComponent.new';
import {
@@ -86,8 +82,6 @@ import {
higherPriorityLane,
getCurrentUpdateLanePriority,
setCurrentUpdateLanePriority,
schedulerPriorityToLanePriority,
lanePriorityToSchedulerPriority,
} from './ReactFiberLane';
import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
import {
@@ -438,19 +432,17 @@ export function attemptHydrationAtCurrentPriority(fiber: Fiber): void {
markRetryLaneIfNotHydrated(fiber, lane);
}
export function runWithPriority<T>(priority: ReactPriorityLevel, fn: () => T) {
export function runWithPriority<T>(priority: LanePriority, fn: () => T) {
const previousPriority = getCurrentUpdateLanePriority();
try {
setCurrentUpdateLanePriority(schedulerPriorityToLanePriority(priority));
setCurrentUpdateLanePriority(priority);
return fn();
} finally {
setCurrentUpdateLanePriority(previousPriority);
}
}
export function getCurrentUpdatePriority(): ReactPriorityLevel {
return lanePriorityToSchedulerPriority(getCurrentUpdateLanePriority());
}
export {getCurrentUpdateLanePriority};
export {findHostInstance};
@@ -7,11 +7,7 @@
* @flow
*/
import type {
Fiber,
ReactPriorityLevel,
SuspenseHydrationCallbacks,
} from './ReactInternalTypes';
import type {Fiber, SuspenseHydrationCallbacks} from './ReactInternalTypes';
import type {FiberRoot} from './ReactInternalTypes';
import type {RootTag} from './ReactRootTags';
import type {
@@ -23,7 +19,7 @@ import type {
import type {RendererInspectionConfig} from './ReactFiberHostConfig';
import {FundamentalComponent} from './ReactWorkTags';
import type {ReactNodeList} from 'shared/ReactTypes';
import type {Lane} from './ReactFiberLane';
import type {Lane, LanePriority} from './ReactFiberLane';
import type {SuspenseState} from './ReactFiberSuspenseComponent.old';
import {
@@ -86,8 +82,6 @@ import {
higherPriorityLane,
getCurrentUpdateLanePriority,
setCurrentUpdateLanePriority,
schedulerPriorityToLanePriority,
lanePriorityToSchedulerPriority,
} from './ReactFiberLane';
import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
import {
@@ -438,19 +432,17 @@ export function attemptHydrationAtCurrentPriority(fiber: Fiber): void {
markRetryLaneIfNotHydrated(fiber, lane);
}
export function runWithPriority<T>(priority: ReactPriorityLevel, fn: () => T) {
export function runWithPriority<T>(priority: LanePriority, fn: () => T) {
const previousPriority = getCurrentUpdateLanePriority();
try {
setCurrentUpdateLanePriority(schedulerPriorityToLanePriority(priority));
setCurrentUpdateLanePriority(priority);
return fn();
} finally {
setCurrentUpdateLanePriority(previousPriority);
}
}
export function getCurrentUpdatePriority(): ReactPriorityLevel {
return lanePriorityToSchedulerPriority(getCurrentUpdateLanePriority());
}
export {getCurrentUpdateLanePriority};
export {findHostInstance};
@@ -14,6 +14,11 @@ let React;
let ReactNoop;
let Scheduler;
// Copied from ReactFiberLanes. Don't do this!
// This is hard coded directly to avoid needing to import, and
// we'll remove this as we replace runWithPriority with React APIs.
const InputContinuousLanePriority = 12;
describe('ReactIncrementalUpdates', () => {
beforeEach(() => {
jest.resetModuleRegistry();
@@ -517,15 +522,13 @@ describe('ReactIncrementalUpdates', () => {
if (log === 'B') {
// Right after B commits, schedule additional updates.
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
ReactNoop.unstable_runWithPriority(
Scheduler.unstable_UserBlockingPriority,
() =>
Scheduler.unstable_runWithPriority(
Scheduler.unstable_UserBlockingPriority,
() => {
pushToLog('C');
},
),
ReactNoop.unstable_runWithPriority(InputContinuousLanePriority, () =>
Scheduler.unstable_runWithPriority(
Scheduler.unstable_UserBlockingPriority,
() => {
pushToLog('C');
},
),
);
setLog(prevLog => prevLog + 'D');
}
@@ -545,15 +548,13 @@ describe('ReactIncrementalUpdates', () => {
pushToLog('A');
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
ReactNoop.unstable_runWithPriority(
Scheduler.unstable_UserBlockingPriority,
() =>
Scheduler.unstable_runWithPriority(
Scheduler.unstable_UserBlockingPriority,
() => {
pushToLog('B');
},
),
ReactNoop.unstable_runWithPriority(InputContinuousLanePriority, () =>
Scheduler.unstable_runWithPriority(
Scheduler.unstable_UserBlockingPriority,
() => {
pushToLog('B');
},
),
);
});
expect(Scheduler).toHaveYielded([
@@ -586,15 +587,13 @@ describe('ReactIncrementalUpdates', () => {
if (this.state.log === 'B') {
// Right after B commits, schedule additional updates.
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
ReactNoop.unstable_runWithPriority(
Scheduler.unstable_UserBlockingPriority,
() =>
Scheduler.unstable_runWithPriority(
Scheduler.unstable_UserBlockingPriority,
() => {
this.pushToLog('C');
},
),
ReactNoop.unstable_runWithPriority(InputContinuousLanePriority, () =>
Scheduler.unstable_runWithPriority(
Scheduler.unstable_UserBlockingPriority,
() => {
this.pushToLog('C');
},
),
);
this.pushToLog('D');
}
@@ -615,15 +614,13 @@ describe('ReactIncrementalUpdates', () => {
await ReactNoop.act(async () => {
pushToLog('A');
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
ReactNoop.unstable_runWithPriority(
Scheduler.unstable_UserBlockingPriority,
() =>
Scheduler.unstable_runWithPriority(
Scheduler.unstable_UserBlockingPriority,
() => {
pushToLog('B');
},
),
ReactNoop.unstable_runWithPriority(InputContinuousLanePriority, () =>
Scheduler.unstable_runWithPriority(
Scheduler.unstable_UserBlockingPriority,
() => {
pushToLog('B');
},
),
);
});
expect(Scheduler).toHaveYielded([
@@ -23,6 +23,11 @@ let onWorkScheduled;
let onWorkStarted;
let onWorkStopped;
// Copied from ReactFiberLanes. Don't do this!
// This is hard coded directly to avoid needing to import, and
// we'll remove this as we replace runWithPriority with React APIs.
const IdleLanePriority = 2;
function loadModules() {
ReactFeatureFlags = require('shared/ReactFeatureFlags');
@@ -233,13 +238,11 @@ describe('ReactDOMTracing', () => {
} else {
Scheduler.unstable_yieldValue('Child:mount');
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
ReactDOM.unstable_runWithPriority(
Scheduler.unstable_IdlePriority,
() =>
Scheduler.unstable_runWithPriority(
Scheduler.unstable_IdlePriority,
() => setDidMount(true),
),
ReactDOM.unstable_runWithPriority(IdleLanePriority, () =>
Scheduler.unstable_runWithPriority(
Scheduler.unstable_IdlePriority,
() => setDidMount(true),
),
);
}
}, [didMount]);