Skip to content

Commit 25d9db5

Browse files
committed
Implement Task priority
Task priority is similar to Synchronous priority. Both are flushed in the current tick. Synchronous priority is flushed immediately (e.g. sync work triggered by setState will flush before setState exits), where as Task is flushed after the current batch of work is committed. Currently used for batchedUpdates and nested sync updates. Task should also be used for componentDidUpdate/Mount and error boundary work. I'll add this in a later commit.
1 parent 4b051f3 commit 25d9db5

File tree

3 files changed

+28
-17
lines changed

3 files changed

+28
-17
lines changed

scripts/fiber/tests-failing.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -554,9 +554,6 @@ src/renderers/shared/stack/reconciler/__tests__/ReactCompositeComponent-test.js
554554
src/renderers/shared/stack/reconciler/__tests__/ReactCompositeComponentNestedState-test.js
555555
* should provide up to date values for props
556556

557-
src/renderers/shared/stack/reconciler/__tests__/ReactCompositeComponentState-test.js
558-
* should support setting state
559-
560557
src/renderers/shared/stack/reconciler/__tests__/ReactEmptyComponent-test.js
561558
* should still throw when rendering to undefined
562559
* should be able to switch between rendering null and a normal tag
@@ -565,6 +562,9 @@ src/renderers/shared/stack/reconciler/__tests__/ReactEmptyComponent-test.js
565562
* throws when rendering null at the top level
566563
* preserves the dom node during updates
567564

565+
src/renderers/shared/stack/reconciler/__tests__/ReactErrorBoundaries-test.js
566+
* lets different boundaries catch their own first errors
567+
568568
src/renderers/shared/stack/reconciler/__tests__/ReactMultiChild-test.js
569569
* should warn for duplicated keys with component stack info
570570

scripts/fiber/tests-passing.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,7 @@ src/renderers/shared/stack/reconciler/__tests__/ReactCompositeComponentDOMMinima
10161016
* should not render extra nodes for non-interpolated text
10171017

10181018
src/renderers/shared/stack/reconciler/__tests__/ReactCompositeComponentState-test.js
1019+
* should support setting state
10191020
* should batch unmounts
10201021

10211022
src/renderers/shared/stack/reconciler/__tests__/ReactEmptyComponent-test.js
@@ -1058,7 +1059,6 @@ src/renderers/shared/stack/reconciler/__tests__/ReactErrorBoundaries-test.js
10581059
* catches errors in componentDidMount
10591060
* catches errors in componentDidUpdate
10601061
* propagates errors inside boundary during componentDidMount
1061-
* lets different boundaries catch their own first errors
10621062

10631063
src/renderers/shared/stack/reconciler/__tests__/ReactIdentity-test.js
10641064
* should allow key property to express identity

src/renderers/shared/fiber/ReactFiberScheduler.js

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
167167
commitInsertion(effectfulFiber);
168168
// Clear the "placement" from effect tag so that we know that this is inserted, before
169169
// any life-cycles like componentDidMount gets called.
170-
effectfulFiber.effectTag = NoEffect;
170+
effectfulFiber.effectTag ^= Placement;
171171
break;
172172
}
173173
case PlacementAndUpdate:
@@ -176,7 +176,7 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
176176
commitInsertion(effectfulFiber);
177177
// Clear the "placement" from effect tag so that we know that this is inserted, before
178178
// any life-cycles like componentDidMount gets called.
179-
effectfulFiber.effectTag = Update;
179+
effectfulFiber.effectTag ^= Placement;
180180

181181
// Update
182182
const current = effectfulFiber.alternate;
@@ -250,6 +250,7 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
250250
if (allTrappedErrors) {
251251
handleErrors(allTrappedErrors);
252252
}
253+
performTaskWork();
253254
}
254255

255256
function resetWorkPriority(workInProgress : Fiber) {
@@ -499,9 +500,9 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
499500
}
500501
}
501502

502-
// function performTaskWork() {
503-
// performAndHandleErrors(TaskPriority);
504-
// }
503+
function performTaskWork() {
504+
performAndHandleErrors(TaskPriority);
505+
}
505506

506507
function performAndHandleErrors(priorityLevel : PriorityLevel, deadline : null | Deadline) {
507508
// The exact priority level doesn't matter, so long as it's in range of the
@@ -611,7 +612,14 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
611612
}
612613

613614
function scheduleWork(root : FiberRoot) {
614-
scheduleWorkAtPriority(root, priorityContext);
615+
let priorityLevel = priorityContext;
616+
617+
// If we're in a batch, switch to task priority
618+
if (priorityLevel === SynchronousPriority && shouldBatchUpdates) {
619+
priorityLevel = TaskPriority;
620+
}
621+
622+
scheduleWorkAtPriority(root, priorityLevel);
615623
}
616624

617625
function scheduleWorkAtPriority(root : FiberRoot, priorityLevel : PriorityLevel) {
@@ -647,10 +655,8 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
647655
function scheduleCallbackAtPriority(priorityLevel : PriorityLevel) {
648656
switch (priorityLevel) {
649657
case SynchronousPriority:
650-
if (!shouldBatchUpdates) {
651-
// Unless in batched mode, perform work immediately
652-
performSynchronousWork();
653-
}
658+
// Perform work immediately
659+
performSynchronousWork();
654660
return;
655661
case TaskPriority:
656662
// Do nothing. Task work should be flushed after committing.
@@ -667,7 +673,12 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
667673
}
668674

669675
function scheduleUpdate(fiber : Fiber) {
670-
const priorityLevel = priorityContext;
676+
let priorityLevel = priorityContext;
677+
// If we're in a batch, switch to task priority
678+
if (priorityLevel === SynchronousPriority && shouldBatchUpdates) {
679+
priorityLevel = TaskPriority;
680+
}
681+
671682
while (true) {
672683
if (fiber.pendingWorkPriority === NoWork ||
673684
fiber.pendingWorkPriority >= priorityLevel) {
@@ -709,9 +720,9 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
709720
return fn();
710721
} finally {
711722
shouldBatchUpdates = prev;
712-
// If we've exited the batch, perform any scheduled sync work
723+
// If we've exited the batch, perform any scheduled task work
713724
if (!shouldBatchUpdates) {
714-
performSynchronousWork();
725+
performTaskWork();
715726
}
716727
}
717728
}

0 commit comments

Comments
 (0)