Only check minPriorityLevel after a commit
Andrew Clark committed
Jun 16, 2017 at 16:50 UTC
443ab45835dab084a4d09ec845238923f98cd894
1 file changed
+62
-45
src/renderers/shared/fiber/ReactFiberScheduler.js
+62
-45
@@ -763,63 +763,80 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
763
}
764
}
765
766
- function workLoop(
767
- minPriorityLevel: PriorityLevel,
768
- deadline: Deadline | null,
769
- ) {
770
- // Clear any errors.
771
- clearErrors();
772
-
773
- if (nextUnitOfWork === null) {
774
- nextUnitOfWork = findNextUnitOfWork();
766
+ function workLoopAsync(minPriorityLevel: PriorityLevel, deadline: Deadline) {
767
+ // Flush asynchronous work until the deadline expires.
768
+ while (nextUnitOfWork !== null && !deadlineHasExpired) {
769
+ if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
770
+ nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
771
+ // In a deferred work batch, iff nextUnitOfWork returns null, we just
772
+ // completed a root and a pendingCommit exists. Logically, we could
773
+ // omit either of the checks in the following condition, but we need
774
+ // both to satisfy Flow.
775
+ if (nextUnitOfWork === null && pendingCommit !== null) {
776
+ // If we have time, we should commit the work now.
777
+ if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
778
+ commitAllWork(pendingCommit);
779
+ nextUnitOfWork = findNextUnitOfWork();
780
+ // Clear any errors that were scheduled during the commit phase.
781
+ clearErrors();
782
+ // The priority level may have changed. Check again.
783
+ if (
784
+ nextPriorityLevel === NoWork ||
785
+ nextPriorityLevel > minPriorityLevel ||
786
+ nextPriorityLevel < HighPriority
787
+ ) {
788
+ // The priority level does not match.
789
+ break;
790
+ }
791
+ } else {
792
+ deadlineHasExpired = true;
793
+ }
794
+ // Otherwise the root will committed in the next frame.
795
+ }
796
+ } else {
797
+ deadlineHasExpired = true;
798
+ }
799
}
800
+ }
801
802
+ function workLoopSync(minPriorityLevel: PriorityLevel) {
803
// Flush all synchronous and task work.
778
- while (
779
- nextUnitOfWork !== null &&
780
- nextPriorityLevel !== NoWork &&
781
- nextPriorityLevel <= minPriorityLevel &&
782
- nextPriorityLevel <= TaskPriority
783
- ) {
804
+ while (nextUnitOfWork !== null) {
805
nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
806
if (nextUnitOfWork === null) {
807
nextUnitOfWork = findNextUnitOfWork();
808
// performUnitOfWork returned null, which means we just committed a
809
// root. Clear any errors that were scheduled during the commit phase.
810
clearErrors();
811
+ // The priority level may have changed. Check again.
812
+ if (
813
+ nextPriorityLevel === NoWork ||
814
+ nextPriorityLevel > minPriorityLevel ||
815
+ nextPriorityLevel > TaskPriority
816
+ ) {
817
+ // The priority level does not match.
818
+ break;
819
+ }
820
}
821
}
822
+ }
823
793
- if (deadline !== null) {
794
- // Flush asynchronous work until the deadline expires.
795
- while (
796
- nextUnitOfWork !== null &&
797
- !deadlineHasExpired &&
798
- nextPriorityLevel !== NoWork &&
799
- nextPriorityLevel <= minPriorityLevel &&
800
- nextPriorityLevel >= HighPriority
801
- ) {
802
- if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
803
- nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
804
- // In a deferred work batch, iff nextUnitOfWork returns null, we just
805
- // completed a root and a pendingCommit exists. Logically, we could
806
- // omit either of the checks in the following condition, but we need
807
- // both to satisfy Flow.
808
- if (nextUnitOfWork === null && pendingCommit !== null) {
809
- // If we have time, we should commit the work now.
810
- if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
811
- commitAllWork(pendingCommit);
812
- nextUnitOfWork = findNextUnitOfWork();
813
- // Clear any errors that were scheduled during the commit phase.
814
- clearErrors();
815
- } else {
816
- deadlineHasExpired = true;
817
- }
818
- // Otherwise the root will committed in the next frame.
819
- }
820
- } else {
821
- deadlineHasExpired = true;
822
- }
824
+ function workLoop(
825
+ minPriorityLevel: PriorityLevel,
826
+ deadline: Deadline | null,
827
+ ) {
828
+ // Clear any errors.
829
+ clearErrors();
830
+
831
+ if (nextUnitOfWork === null) {
832
+ nextUnitOfWork = findNextUnitOfWork();
833
+ }
834
+
835
+ if (nextPriorityLevel !== NoWork && nextPriorityLevel <= minPriorityLevel) {
836
+ if (nextPriorityLevel <= TaskPriority) {
837
+ workLoopSync(minPriorityLevel);
838
+ } else if (deadline !== null) {
839
+ workLoopAsync(minPriorityLevel, deadline);
840
}
841
}
842
}