Skip to content

Commit 03ede83

Browse files
authored
Use EventPriority to track update priority (#21082)
Instead of LanePriority. Internally, EventPriority is just a lane, so this skips an extra conversion. Since EventPriority is a "public" (to the host config) type, I was also able to remove some deep imports of the Lane module. This gets us most of the way to deleting the LanePriority entirely.
1 parent 6a589ad commit 03ede83

25 files changed

Lines changed: 484 additions & 479 deletions

‎packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,7 @@ let ReactFeatureFlags;
1717
letSuspense;
1818
letSuspenseList;
1919
letact;
20-
21-
// Copied from ReactFiberLanes. Don't do this!
22-
// This is hard coded directly to avoid needing to import, and
23-
// we'll remove this as we replace runWithPriority with React APIs.
24-
exportconstIdleLanePriority=2;
20+
letIdleEventPriority;
2521

2622
functiondispatchMouseEvent(to,from){
2723
if(!to){
@@ -89,6 +85,8 @@ describe('ReactDOMServerPartialHydration', () => {
8985
Scheduler=require('scheduler');
9086
Suspense=React.Suspense;
9187
SuspenseList=React.SuspenseList;
88+
89+
IdleEventPriority=require('react-reconciler/constants').IdleEventPriority;
9290
});
9391

9492
// Note: This is based on a similar component we use in www. We can delete
@@ -628,7 +626,7 @@ describe('ReactDOMServerPartialHydration', () => {
628626
expect(span.textContent).toBe('Hello');
629627

630628
// Schedule an update at idle priority
631-
ReactDOM.unstable_runWithPriority(IdleLanePriority,()=>{
629+
ReactDOM.unstable_runWithPriority(IdleEventPriority,()=>{
632630
root.render(<Apptext="Hi"className="hi"/>);
633631
});
634632

‎packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ let Scheduler;
1919
letSuspense;
2020
letact;
2121

22-
// Copied from ReactFiberLanes. Don't do this!
23-
// This is hard coded directly to avoid needing to import, and
24-
// we'll remove this as we replace runWithPriority with React APIs.
25-
exportconstIdleLanePriority=2;
22+
letIdleEventPriority;
2623

2724
functiondispatchMouseHoverEvent(to,from){
2825
if(!to){
@@ -101,7 +98,7 @@ function dispatchClickEvent(target) {
10198
// and there's no native DOM event that maps to idle priority, so this is a
10299
// temporary workaround. Need something like ReactDOM.unstable_IdleUpdates.
103100
functionTODO_scheduleIdleDOMSchedulerTask(fn){
104-
ReactDOM.unstable_runWithPriority(IdleLanePriority,()=>{
101+
ReactDOM.unstable_runWithPriority(IdleEventPriority,()=>{
105102
constprevEvent=window.event;
106103
window.event={type: 'message'};
107104
try{
@@ -125,6 +122,8 @@ describe('ReactDOMServerSelectiveHydration', () => {
125122
act=ReactTestUtils.unstable_concurrentAct;
126123
Scheduler=require('scheduler');
127124
Suspense=React.Suspense;
125+
126+
IdleEventPriority=require('react-reconciler/constants').IdleEventPriority;
128127
});
129128

130129
// @gate experimental

‎packages/react-dom/src/client/ReactDOM.js‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ import {
3535
attemptDiscreteHydration,
3636
attemptContinuousHydration,
3737
attemptHydrationAtCurrentPriority,
38-
runWithPriority,
39-
getCurrentUpdateLanePriority,
4038
}from'react-reconciler/src/ReactFiberReconciler';
39+
import{
40+
runWithPriority,
41+
getCurrentUpdatePriority,
42+
}from'react-reconciler/src/ReactEventPriorities';
4143
import{createPortalascreatePortalImpl}from'react-reconciler/src/ReactPortal';
4244
import{canUseDOM}from'shared/ExecutionEnvironment';
4345
importReactVersionfrom'shared/ReactVersion';
@@ -74,7 +76,7 @@ setAttemptSynchronousHydration(attemptSynchronousHydration);
7476
setAttemptDiscreteHydration(attemptDiscreteHydration);
7577
setAttemptContinuousHydration(attemptContinuousHydration);
7678
setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority);
77-
setGetCurrentUpdatePriority(getCurrentUpdateLanePriority);
79+
setGetCurrentUpdatePriority(getCurrentUpdatePriority);
7880
setAttemptHydrationAtPriority(runWithPriority);
7981

8082
letdidWarnAboutUnstableCreatePortal=false;

‎packages/react-dom/src/events/ReactDOMEventListener.js‎

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,6 @@ import {
4444
discreteUpdates,
4545
}from'./ReactDOMUpdateBatching';
4646

47-
import{
48-
InputContinuousLanePriorityasInputContinuousLanePriority_old,
49-
getCurrentUpdateLanePriorityasgetCurrentUpdateLanePriority_old,
50-
setCurrentUpdateLanePriorityassetCurrentUpdateLanePriority_old,
51-
}from'react-reconciler/src/ReactFiberLane.old';
52-
import{
53-
InputContinuousLanePriorityasInputContinuousLanePriority_new,
54-
getCurrentUpdateLanePriorityasgetCurrentUpdateLanePriority_new,
55-
setCurrentUpdateLanePriorityassetCurrentUpdateLanePriority_new,
56-
}from'react-reconciler/src/ReactFiberLane.new';
5747
import{getCurrentPriorityLevelasgetCurrentPriorityLevel_old}from'react-reconciler/src/SchedulerWithReactIntegration.old';
5848
import{
5949
getCurrentPriorityLevelasgetCurrentPriorityLevel_new,
@@ -68,19 +58,10 @@ import {
6858
ContinuousEventPriority,
6959
DefaultEventPriority,
7060
IdleEventPriority,
61+
getCurrentUpdatePriority,
62+
setCurrentUpdatePriority,
7163
}from'react-reconciler/src/ReactEventPriorities';
7264

73-
// TODO: These should use the opaque EventPriority type instead of LanePriority.
74-
// Then internally we can use a Lane.
75-
constInputContinuousLanePriority=enableNewReconciler
76-
? InputContinuousLanePriority_new
77-
: InputContinuousLanePriority_old;
78-
constgetCurrentUpdateLanePriority=enableNewReconciler
79-
? getCurrentUpdateLanePriority_new
80-
: getCurrentUpdateLanePriority_old;
81-
constsetCurrentUpdateLanePriority=enableNewReconciler
82-
? setCurrentUpdateLanePriority_new
83-
: setCurrentUpdateLanePriority_old;
8465
constgetCurrentPriorityLevel=enableNewReconciler
8566
? getCurrentPriorityLevel_new
8667
: getCurrentPriorityLevel_old;
@@ -167,12 +148,12 @@ function dispatchContinuousEvent(
167148
container,
168149
nativeEvent,
169150
){
170-
constpreviousPriority=getCurrentUpdateLanePriority();
151+
constpreviousPriority=getCurrentUpdatePriority();
171152
try{
172-
setCurrentUpdateLanePriority(InputContinuousLanePriority);
153+
setCurrentUpdatePriority(ContinuousEventPriority);
173154
dispatchEvent(domEventName,eventSystemFlags,container,nativeEvent);
174155
}finally{
175-
setCurrentUpdateLanePriority(previousPriority);
156+
setCurrentUpdatePriority(previousPriority);
176157
}
177158
}
178159

‎packages/react-dom/src/events/ReactDOMEventReplaying.js‎

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
1212
importtype{DOMEventName}from'../events/DOMEventNames';
1313
importtype{EventSystemFlags}from'./EventSystemFlags';
1414
importtype{FiberRoot}from'react-reconciler/src/ReactInternalTypes';
15-
importtype{LanePriority}from'react-reconciler/src/ReactFiberLane.old';
15+
importtype{EventPriority}from'react-reconciler/src/ReactEventPriorities';
1616

1717
import{enableSelectiveHydration}from'shared/ReactFeatureFlags';
1818
import{
@@ -30,6 +30,7 @@ import {
3030
getClosestInstanceFromNode,
3131
}from'../client/ReactDOMComponentTree';
3232
import{HostRoot,SuspenseComponent}from'react-reconciler/src/ReactWorkTags';
33+
import{isHigherEventPriority}from'react-reconciler/src/ReactEventPriorities';
3334

3435
let attemptSynchronousHydration: (fiber: Object)=>void;
3536

@@ -57,16 +58,16 @@ export function setAttemptHydrationAtCurrentPriority(
5758
attemptHydrationAtCurrentPriority=fn;
5859
}
5960

60-
let getCurrentUpdatePriority: ()=>LanePriority;
61+
let getCurrentUpdatePriority: ()=>EventPriority;
6162

62-
exportfunctionsetGetCurrentUpdatePriority(fn: ()=>LanePriority){
63+
exportfunctionsetGetCurrentUpdatePriority(fn: ()=>EventPriority){
6364
getCurrentUpdatePriority=fn;
6465
}
6566

66-
letattemptHydrationAtPriority: <T>(priority: LanePriority, fn: () =>T)=>T;
67+
letattemptHydrationAtPriority: <T>(priority: EventPriority, fn: () =>T)=>T;
6768

6869
exportfunctionsetAttemptHydrationAtPriority(
69-
fn: <T>(priority: LanePriority,fn: ()=>T)=>T,
70+
fn: <T>(priority: EventPriority,fn: ()=>T)=>T,
7071
){
7172
attemptHydrationAtPriority=fn;
7273
}
@@ -109,7 +110,7 @@ const queuedPointerCaptures: Map<number, QueuedReplayableEvent> = new Map();
109110
typeQueuedHydrationTarget={|
110111
blockedOn: null|Container|SuspenseInstance,
111112
target: Node,
112-
lanePriority: LanePriority,
113+
priority: EventPriority,
113114
|};
114115
constqueuedExplicitHydrationTargets: Array<QueuedHydrationTarget>=[];
115116

@@ -390,7 +391,7 @@ function attemptExplicitHydrationTarget(
390391
// We're blocked on hydrating this boundary.
391392
// Increase its priority.
392393
queuedTarget.blockedOn=instance;
393-
attemptHydrationAtPriority(queuedTarget.lanePriority,()=>{
394+
attemptHydrationAtPriority(queuedTarget.priority,()=>{
394395
attemptHydrationAtCurrentPriority(nearestMounted);
395396
});
396397

@@ -412,16 +413,23 @@ function attemptExplicitHydrationTarget(
412413

413414
exportfunctionqueueExplicitHydrationTarget(target: Node): void{
414415
if(enableSelectiveHydration){
415-
constupdateLanePriority=getCurrentUpdatePriority();
416+
// TODO: This will read the priority if it's dispatched by the React
417+
// event system but not native events. Should read window.event.type, like
418+
// we do for updates (getCurrentEventPriority).
419+
constupdatePriority=getCurrentUpdatePriority();
416420
constqueuedTarget: QueuedHydrationTarget={
417421
blockedOn: null,
418422
target: target,
419-
lanePriority: updateLanePriority,
423+
priority: updatePriority,
420424
};
421425
leti=0;
422426
for(;i<queuedExplicitHydrationTargets.length;i++){
427+
// Stop once we hit the first target with lower priority than
423428
if(
424-
updateLanePriority<=queuedExplicitHydrationTargets[i].lanePriority
429+
!isHigherEventPriority(
430+
updatePriority,
431+
queuedExplicitHydrationTargets[i].priority,
432+
)
425433
){
426434
break;
427435
}

‎packages/react-reconciler/src/ReactEventPriorities.js‎

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,61 @@ import {
1414
ContinuousEventPriorityasContinuousEventPriority_old,
1515
DefaultEventPriorityasDefaultEventPriority_old,
1616
IdleEventPriorityasIdleEventPriority_old,
17+
getCurrentUpdatePriorityasgetCurrentUpdatePriority_old,
18+
setCurrentUpdatePriorityassetCurrentUpdatePriority_old,
19+
runWithPriorityasrunWithPriority_old,
20+
isHigherEventPriorityasisHigherEventPriority_old,
1721
}from'./ReactEventPriorities.old';
1822

1923
import{
2024
DiscreteEventPriorityasDiscreteEventPriority_new,
2125
ContinuousEventPriorityasContinuousEventPriority_new,
2226
DefaultEventPriorityasDefaultEventPriority_new,
2327
IdleEventPriorityasIdleEventPriority_new,
28+
getCurrentUpdatePriorityasgetCurrentUpdatePriority_new,
29+
setCurrentUpdatePriorityassetCurrentUpdatePriority_new,
30+
runWithPriorityasrunWithPriority_new,
31+
isHigherEventPriorityasisHigherEventPriority_new,
2432
}from'./ReactEventPriorities.new';
2533

26-
exportconstDiscreteEventPriority=enableNewReconciler
27-
? DiscreteEventPriority_new
28-
: DiscreteEventPriority_old;
29-
exportconstContinuousEventPriority=enableNewReconciler
30-
? ContinuousEventPriority_new
31-
: ContinuousEventPriority_old;
32-
exportconstDefaultEventPriority=enableNewReconciler
33-
? DefaultEventPriority_new
34-
: DefaultEventPriority_old;
35-
exportconstIdleEventPriority=enableNewReconciler
36-
? IdleEventPriority_new
37-
: IdleEventPriority_old;
34+
exportopaquetypeEventPriority=number;
35+
36+
exportconstDiscreteEventPriority: EventPriority=enableNewReconciler
37+
? (DiscreteEventPriority_new: any)
38+
: (DiscreteEventPriority_old: any);
39+
exportconstContinuousEventPriority: EventPriority=enableNewReconciler
40+
? (ContinuousEventPriority_new: any)
41+
: (ContinuousEventPriority_old: any);
42+
exportconstDefaultEventPriority: EventPriority=enableNewReconciler
43+
? (DefaultEventPriority_new: any)
44+
: (DefaultEventPriority_old: any);
45+
exportconstIdleEventPriority: EventPriority=enableNewReconciler
46+
? (IdleEventPriority_new: any)
47+
: (IdleEventPriority_old: any);
48+
49+
exportfunctionrunWithPriority<T>(priority: EventPriority,fn: ()=>T): T{
50+
returnenableNewReconciler
51+
? runWithPriority_new((priority: any),fn)
52+
: runWithPriority_old((priority: any),fn);
53+
}
54+
55+
exportfunctiongetCurrentUpdatePriority(): EventPriority{
56+
returnenableNewReconciler
57+
? (getCurrentUpdatePriority_new(): any)
58+
: (getCurrentUpdatePriority_old(): any);
59+
}
60+
61+
exportfunctionsetCurrentUpdatePriority(priority: EventPriority){
62+
returnenableNewReconciler
63+
? setCurrentUpdatePriority_new((priority: any))
64+
: setCurrentUpdatePriority_old((priority: any));
65+
}
66+
67+
exportfunctionisHigherEventPriority(
68+
a: EventPriority,
69+
b: EventPriority,
70+
): boolean{
71+
returnenableNewReconciler
72+
? isHigherEventPriority_new((a: any),(b: any))
73+
: isHigherEventPriority_old((a: any),(b: any));
74+
}

‎packages/react-reconciler/src/ReactEventPriorities.new.js‎

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,69 @@
77
* @flow
88
*/
99

10-
export{
11-
SyncLaneasDiscreteEventPriority,
12-
InputContinuousLaneasContinuousEventPriority,
13-
DefaultLaneasDefaultEventPriority,
14-
IdleLaneasIdleEventPriority,
10+
importtype{Lane,Lanes}from'./ReactFiberLane.new';
11+
12+
import{
13+
NoLane,
14+
SyncLane,
15+
InputContinuousLane,
16+
DefaultLane,
17+
IdleLane,
18+
getHighestPriorityLane,
19+
includesNonIdleWork,
1520
}from'./ReactFiberLane.new';
21+
22+
exportopaquetypeEventPriority=Lane;
23+
24+
exportconstDiscreteEventPriority: EventPriority=SyncLane;
25+
exportconstContinuousEventPriority: EventPriority=InputContinuousLane;
26+
exportconstDefaultEventPriority: EventPriority=DefaultLane;
27+
exportconstIdleEventPriority: EventPriority=IdleLane;
28+
29+
let currentUpdatePriority: EventPriority=NoLane;
30+
31+
exportfunctiongetCurrentUpdatePriority(): EventPriority{
32+
returncurrentUpdatePriority;
33+
}
34+
35+
exportfunctionsetCurrentUpdatePriority(newPriority: EventPriority){
36+
currentUpdatePriority=newPriority;
37+
}
38+
39+
exportfunctionrunWithPriority<T>(priority: EventPriority,fn: ()=>T): T{
40+
constpreviousPriority=currentUpdatePriority;
41+
try{
42+
currentUpdatePriority=priority;
43+
returnfn();
44+
}finally{
45+
currentUpdatePriority=previousPriority;
46+
}
47+
}
48+
49+
exportfunctionhigherEventPriority(
50+
a: EventPriority,
51+
b: EventPriority,
52+
): EventPriority{
53+
returna!==0&&a<b ? a : b;
54+
}
55+
56+
exportfunctionisHigherEventPriority(
57+
a: EventPriority,
58+
b: EventPriority,
59+
): boolean{
60+
returna!==0&&a<b;
61+
}
62+
63+
exportfunctionlanesToEventPriority(lanes: Lanes): EventPriority{
64+
constlane=getHighestPriorityLane(lanes);
65+
if(!isHigherEventPriority(DiscreteEventPriority,lane)){
66+
returnDiscreteEventPriority;
67+
}
68+
if(!isHigherEventPriority(ContinuousEventPriority,lane)){
69+
returnContinuousEventPriority;
70+
}
71+
if(includesNonIdleWork(lane)){
72+
returnDefaultEventPriority;
73+
}
74+
returnIdleEventPriority;
75+
}

0 commit comments

Comments
 (0)