@samitouri / QOS-React / commits / 7b9ae92058

Updates should use the same priority context as top-level render

A bit of restructuring so that setState uses whatever the current priority context is, like top-level render already does. Renamed defaultPriority to priorityContext, and added a new variable called defaultPriorityContext. Having two separate variables allows the default to be changed without interfering with the current context.

Andrew Clark committed Oct 28, 2016 at 11:26 UTC 7b9ae92058150494d372cfe17a8c086a307ee677
3 files changed +45 -22
src/renderers/shared/fiber/ReactFiberBeginWork.js
+1 -1
@@ -48,7 +48,7 @@ var ReactFiberClassComponent = require('ReactFiberClassComponent');
48
49 module.exports = function<T, P, I, TI, C>(
50 config : HostConfig<T, P, I, TI, C>,
51 - scheduleUpdate : (fiber: Fiber, priorityLevel : PriorityLevel) => void
51 + scheduleUpdate : (fiber: Fiber, priorityLevel : ?PriorityLevel) => void
52 ) {
53
54 const {
src/renderers/shared/fiber/ReactFiberClassComponent.js
+6 -7
@@ -16,7 +16,6 @@ import type { Fiber } from 'ReactFiber';
16 import type { PriorityLevel } from 'ReactPriorityLevel';
17 import type { UpdateQueue } from 'ReactFiberUpdateQueue';
18
19 -var { LowPriority } = require('ReactPriorityLevel');
19 var {
20 createUpdateQueue,
21 addToQueue,
@@ -27,16 +26,16 @@ var { isMounted } = require('ReactFiberTreeReflection');
26 var ReactInstanceMap = require('ReactInstanceMap');
27 var shallowEqual = require('shallowEqual');
28
30 -module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : PriorityLevel) => void) {
29 +module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : ?PriorityLevel) => void) {
30
32 - function scheduleUpdateQueue(fiber: Fiber, updateQueue: UpdateQueue, priorityLevel : PriorityLevel) {
31 + function scheduleUpdateQueue(fiber: Fiber, updateQueue: UpdateQueue) {
32 fiber.updateQueue = updateQueue;
33 // Schedule update on the alternate as well, since we don't know which tree
34 // is current.
35 if (fiber.alternate) {
36 fiber.alternate.updateQueue = updateQueue;
37 }
39 - scheduleUpdate(fiber, priorityLevel);
38 + scheduleUpdate(fiber);
39 }
40
41 // Class component state updater
@@ -47,19 +46,19 @@ module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : Priori
46 const updateQueue = fiber.updateQueue ?
47 addToQueue(fiber.updateQueue, partialState) :
48 createUpdateQueue(partialState);
50 - scheduleUpdateQueue(fiber, updateQueue, LowPriority);
49 + scheduleUpdateQueue(fiber, updateQueue);
50 },
51 enqueueReplaceState(instance, state) {
52 const fiber = ReactInstanceMap.get(instance);
53 const updateQueue = createUpdateQueue(state);
54 updateQueue.isReplace = true;
56 - scheduleUpdateQueue(fiber, updateQueue, LowPriority);
55 + scheduleUpdateQueue(fiber, updateQueue);
56 },
57 enqueueForceUpdate(instance) {
58 const fiber = ReactInstanceMap.get(instance);
59 const updateQueue = fiber.updateQueue || createUpdateQueue(null);
60 updateQueue.isForced = true;
62 - scheduleUpdateQueue(fiber, updateQueue, LowPriority);
61 + scheduleUpdateQueue(fiber, updateQueue);
62 },
63 enqueueCallback(instance, callback) {
64 const fiber = ReactInstanceMap.get(instance);
src/renderers/shared/fiber/ReactFiberScheduler.js
+38 -14
@@ -63,8 +63,10 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
63 const scheduleAnimationCallback = config.scheduleAnimationCallback;
64 const scheduleDeferredCallback = config.scheduleDeferredCallback;
65
66 - // The default priority to use for updates.
67 - let defaultPriority : PriorityLevel = LowPriority;
66 + // The priority level to use when scheduling an update.
67 + let priorityContext : (PriorityLevel | null) = null;
68 + // The priority level to use if there is no priority context.
69 + let defaultPriorityContext : PriorityLevel = LowPriority;
70
71 // The next work in progress fiber that we're currently working on.
72 let nextUnitOfWork : ?Fiber = null;
@@ -485,7 +487,7 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
487 while (nextUnitOfWork &&
488 nextPriorityLevel === SynchronousPriority) {
489 nextUnitOfWork = performUnitOfWork(nextUnitOfWork, false);
488 - // If there's no nextUnitForWork, we don't need to search for more
490 + // If there's no nextUnitOfWork, we don't need to search for more
491 // because it shouldn't be possible to schedule sync work without
492 // immediately performing it
493 }
@@ -591,23 +593,45 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
593 }
594 }
595
594 - function scheduleWork(root : FiberRoot) {
595 - if (defaultPriority === SynchronousPriority) {
596 + function scheduleWork(root : FiberRoot, priorityLevel : ?PriorityLevel) {
597 + if (priorityLevel == null) {
598 + priorityLevel = priorityContext !== null ?
599 + priorityContext :
600 + defaultPriorityContext;
601 + }
602 +
603 + if (priorityLevel === SynchronousPriority) {
604 root.current.pendingWorkPriority = SynchronousPriority;
605 performSynchronousWork();
606 }
607
600 - if (defaultPriority === NoWork) {
608 + if (priorityLevel === NoWork) {
609 return;
610 }
603 - if (defaultPriority > AnimationPriority) {
604 - scheduleDeferredWork(root, defaultPriority);
611 + if (priorityLevel > AnimationPriority) {
612 + scheduleDeferredWork(root, priorityLevel);
613 return;
614 }
607 - scheduleAnimationWork(root, defaultPriority);
615 + scheduleAnimationWork(root, priorityLevel);
616 }
617
610 - function scheduleUpdate(fiber: Fiber, priorityLevel : PriorityLevel): void {
618 + function scheduleUpdate(fiber: Fiber, priorityLevel : ?PriorityLevel): void {
619 + // Use priority context if no priority is provided
620 + if (priorityLevel == null) {
621 + priorityLevel = priorityContext !== null ?
622 + priorityContext :
623 + defaultPriorityContext;
624 + }
625 +
626 + // Don't bother bubbling the priority to the root if it is synchronous. Just
627 + // perform it now.
628 + if (priorityLevel === SynchronousPriority) {
629 + fiber.pendingWorkPriority = SynchronousPriority;
630 + nextUnitOfWork = fiber;
631 + performSynchronousWork();
632 + return;
633 + }
634 +
635 while (true) {
636 if (fiber.pendingWorkPriority === NoWork ||
637 fiber.pendingWorkPriority >= priorityLevel) {
@@ -622,7 +646,7 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
646 if (!fiber.return) {
647 if (fiber.tag === HostContainer) {
648 const root : FiberRoot = (fiber.stateNode : any);
625 - scheduleDeferredWork(root, priorityLevel);
649 + scheduleWork(root, priorityLevel);
650 return;
651 } else {
652 throw new Error('Invalid root');
@@ -633,12 +657,12 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
657 }
658
659 function performWithPriority(priorityLevel : PriorityLevel, fn : Function) {
636 - const previousDefaultPriority = defaultPriority;
637 - defaultPriority = priorityLevel;
660 + const previousPriorityContext = priorityContext;
661 + priorityContext = priorityLevel;
662 try {
663 fn();
664 } finally {
641 - defaultPriority = previousDefaultPriority;
665 + priorityContext = previousPriorityContext;
666 }
667 }
668