Skip to content

Commit 4a023c8

Browse files
committed
Exit early in scheduleUpdate if a node's priority matches
This is a performance optimization and is unobservable. However, it helps protect against regressions on the following invariants on which it relies: - The priority of a fiber is greater than or equal to the priority of all its descendent fibers. - If a tree has pending work priority, its root is scheduled.
1 parent defb148 commit 4a023c8

File tree

3 files changed

+23
-16
lines changed

3 files changed

+23
-16
lines changed

scripts/fiber/tests-failing.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@ src/renderers/art/__tests__/ReactART-test.js
3838
* resolves refs before componentDidMount
3939
* resolves refs before componentDidUpdate
4040

41-
src/renderers/dom/__tests__/ReactDOMProduction-test.js
42-
* should throw with an error code in production
43-
4441
src/renderers/dom/shared/__tests__/CSSPropertyOperations-test.js
4542
* should set style attribute when styles exist
4643

scripts/fiber/tests-passing.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ src/renderers/dom/__tests__/ReactDOMProduction-test.js
470470
* should use prod React
471471
* should handle a simple flow
472472
* should call lifecycle methods
473+
* should throw with an error code in production
473474

474475
src/renderers/dom/fiber/__tests__/ReactDOMFiber-test.js
475476
* should render strings as children

src/renderers/shared/fiber/ReactFiberScheduler.js

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -704,27 +704,36 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
704704
priorityLevel = TaskPriority;
705705
}
706706

707-
while (true) {
708-
if (fiber.pendingWorkPriority === NoWork ||
709-
fiber.pendingWorkPriority >= priorityLevel) {
710-
fiber.pendingWorkPriority = priorityLevel;
707+
let node = fiber;
708+
let shouldContinue = true;
709+
while (node && shouldContinue) {
710+
// Walk the parent path to the root and update each node's priority. Once
711+
// we reach a node whose priority matches (and whose alternate's priority
712+
// matches) we can exit safely knowing that the rest of the path is correct.
713+
shouldContinue = false;
714+
if (node.pendingWorkPriority === NoWork ||
715+
node.pendingWorkPriority >= priorityLevel) {
716+
// Priority did not match. Update and keep going.
717+
shouldContinue = true;
718+
node.pendingWorkPriority = priorityLevel;
711719
}
712-
if (fiber.alternate) {
713-
if (fiber.alternate.pendingWorkPriority === NoWork ||
714-
fiber.alternate.pendingWorkPriority >= priorityLevel) {
715-
fiber.alternate.pendingWorkPriority = priorityLevel;
720+
if (node.alternate) {
721+
if (node.alternate.pendingWorkPriority === NoWork ||
722+
node.alternate.pendingWorkPriority >= priorityLevel) {
723+
// Priority did not match. Update and keep going.
724+
shouldContinue = true;
725+
node.alternate.pendingWorkPriority = priorityLevel;
716726
}
717727
}
718-
if (!fiber.return) {
719-
if (fiber.tag === HostContainer) {
720-
const root : FiberRoot = (fiber.stateNode : any);
728+
if (!node.return) {
729+
if (node.tag === HostContainer) {
730+
const root : FiberRoot = (node.stateNode : any);
721731
scheduleWorkAtPriority(root, priorityLevel);
722-
return;
723732
} else {
724733
throw new Error('Invalid root');
725734
}
726735
}
727-
fiber = fiber.return;
736+
node = node.return;
728737
}
729738
}
730739

0 commit comments

Comments
 (0)