Skip to content

Commit

Permalink
clean up isInputPending in Scheduler (#28444)
Browse files Browse the repository at this point in the history
## Summary

`isInputPending` is not in use. This PR cleans up the flags controlling
its gating and parameters to simplify Scheduler.

Makes `frameYieldMs` feature flag static, set to 10ms in www, which we
found built on the wins provided by a broader yield interval via
`isInputPending`. Flag remains set to 5ms in OSS builds.

## How did you test this change?
`yarn test Scheduler`

DiffTrain build for [3bcd2de](3bcd2de)
  • Loading branch information
noahlemen committed Feb 27, 2024
1 parent b29a80f commit 9509de9
Show file tree
Hide file tree
Showing 11 changed files with 43 additions and 291 deletions.
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2f240c91ed54900adee213565cb2039e161629e9
3bcd2de01b5716202eabe8faa338f51bdc59ce26
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -617,4 +617,4 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactCurrentDispatcher.current.useTransition();
};
exports.version = "18.3.0-www-modern-e541e76b";
exports.version = "18.3.0-www-modern-29517cf7";
2 changes: 1 addition & 1 deletion compiled/facebook-www/React-profiling.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactCurrentDispatcher.current.useTransition();
};
exports.version = "18.3.0-www-modern-4a897bb7";
exports.version = "18.3.0-www-modern-9c6d816f";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
73 changes: 5 additions & 68 deletions compiled/facebook-www/Scheduler-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,8 @@ if (__DEV__) {
var userBlockingPriorityTimeout =
dynamicFeatureFlags.userBlockingPriorityTimeout,
normalPriorityTimeout = dynamicFeatureFlags.normalPriorityTimeout,
lowPriorityTimeout = dynamicFeatureFlags.lowPriorityTimeout,
enableIsInputPending = dynamicFeatureFlags.enableIsInputPending,
enableIsInputPendingContinuous =
dynamicFeatureFlags.enableIsInputPendingContinuous,
frameYieldMs = dynamicFeatureFlags.frameYieldMs,
continuousYieldMs = dynamicFeatureFlags.continuousYieldMs,
maxYieldMs = dynamicFeatureFlags.maxYieldMs;
lowPriorityTimeout = dynamicFeatureFlags.lowPriorityTimeout;
var frameYieldMs = 10;
var enableProfiling = enableProfilingFeatureFlag;

function push(heap, node) {
Expand Down Expand Up @@ -297,16 +292,6 @@ if (__DEV__) {
var localSetImmediate =
typeof setImmediate !== "undefined" ? setImmediate : null; // IE and Node.js + jsdom

var isInputPending =
typeof navigator !== "undefined" && // $FlowFixMe[prop-missing]
navigator.scheduling !== undefined && // $FlowFixMe[incompatible-type]
navigator.scheduling.isInputPending !== undefined
? navigator.scheduling.isInputPending.bind(navigator.scheduling)
: null;
var continuousOptions = {
includeContinuous: enableIsInputPendingContinuous
};

function advanceTimers(currentTime) {
// Check for tasks that are no longer delayed and add them to the queue.
var timer = peek(timerQueue);
Expand Down Expand Up @@ -684,10 +669,7 @@ if (__DEV__) {
// need to be frame aligned; for those that do, use requestAnimationFrame.

var frameInterval = frameYieldMs;
var continuousInputInterval = continuousYieldMs;
var maxInterval = maxYieldMs;
var startTime = -1;
var needsPaint = false;

function shouldYieldToHost() {
var timeElapsed = exports.unstable_now() - startTime;
Expand All @@ -696,54 +678,12 @@ if (__DEV__) {
// The main thread has only been blocked for a really short amount of time;
// smaller than a single frame. Don't yield yet.
return false;
} // The main thread has been blocked for a non-negligible amount of time. We
// may want to yield control of the main thread, so the browser can perform
// high priority tasks. The main ones are painting and user input. If there's
// a pending paint or a pending input, then we should yield. But if there's
// neither, then we can yield less often while remaining responsive. We'll
// eventually yield regardless, since there could be a pending paint that
// wasn't accompanied by a call to `requestPaint`, or other main thread tasks
// like network events.

if (enableIsInputPending) {
if (needsPaint) {
// There's a pending paint (signaled by `requestPaint`). Yield now.
return true;
}

if (timeElapsed < continuousInputInterval) {
// We haven't blocked the thread for that long. Only yield if there's a
// pending discrete input (e.g. click). It's OK if there's pending
// continuous input (e.g. mouseover).
if (isInputPending !== null) {
return isInputPending();
}
} else if (timeElapsed < maxInterval) {
// Yield if there's either a pending discrete or continuous input.
if (isInputPending !== null) {
return isInputPending(continuousOptions);
}
} else {
// We've blocked the thread for a long time. Even if there's no pending
// input, there may be some other scheduled work that we don't know about,
// like a network event. Yield now.
return true;
}
} // `isInputPending` isn't available. Yield now.
} // Yield now.

return true;
}

function requestPaint() {
if (
enableIsInputPending &&
navigator !== undefined && // $FlowFixMe[prop-missing]
navigator.scheduling !== undefined && // $FlowFixMe[incompatible-type]
navigator.scheduling.isInputPending !== undefined
) {
needsPaint = true;
} // Since we yield every frame regardless, `requestPaint` has no effect.
}
function requestPaint() {}

function forceFrameRate(fps) {
if (fps < 0 || fps > 125) {
Expand Down Expand Up @@ -788,10 +728,7 @@ if (__DEV__) {
isMessageLoopRunning = false;
}
}
} // Yielding to the browser will give it a chance to paint, so we can
// reset this.

needsPaint = false;
}
};

var schedulePerformWorkUntilDeadline;
Expand Down
73 changes: 5 additions & 68 deletions compiled/facebook-www/Scheduler-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,8 @@ if (__DEV__) {
var userBlockingPriorityTimeout =
dynamicFeatureFlags.userBlockingPriorityTimeout,
normalPriorityTimeout = dynamicFeatureFlags.normalPriorityTimeout,
lowPriorityTimeout = dynamicFeatureFlags.lowPriorityTimeout,
enableIsInputPending = dynamicFeatureFlags.enableIsInputPending,
enableIsInputPendingContinuous =
dynamicFeatureFlags.enableIsInputPendingContinuous,
frameYieldMs = dynamicFeatureFlags.frameYieldMs,
continuousYieldMs = dynamicFeatureFlags.continuousYieldMs,
maxYieldMs = dynamicFeatureFlags.maxYieldMs;
lowPriorityTimeout = dynamicFeatureFlags.lowPriorityTimeout;
var frameYieldMs = 10;
var enableProfiling = enableProfilingFeatureFlag;

function push(heap, node) {
Expand Down Expand Up @@ -297,16 +292,6 @@ if (__DEV__) {
var localSetImmediate =
typeof setImmediate !== "undefined" ? setImmediate : null; // IE and Node.js + jsdom

var isInputPending =
typeof navigator !== "undefined" && // $FlowFixMe[prop-missing]
navigator.scheduling !== undefined && // $FlowFixMe[incompatible-type]
navigator.scheduling.isInputPending !== undefined
? navigator.scheduling.isInputPending.bind(navigator.scheduling)
: null;
var continuousOptions = {
includeContinuous: enableIsInputPendingContinuous
};

function advanceTimers(currentTime) {
// Check for tasks that are no longer delayed and add them to the queue.
var timer = peek(timerQueue);
Expand Down Expand Up @@ -684,10 +669,7 @@ if (__DEV__) {
// need to be frame aligned; for those that do, use requestAnimationFrame.

var frameInterval = frameYieldMs;
var continuousInputInterval = continuousYieldMs;
var maxInterval = maxYieldMs;
var startTime = -1;
var needsPaint = false;

function shouldYieldToHost() {
var timeElapsed = exports.unstable_now() - startTime;
Expand All @@ -696,54 +678,12 @@ if (__DEV__) {
// The main thread has only been blocked for a really short amount of time;
// smaller than a single frame. Don't yield yet.
return false;
} // The main thread has been blocked for a non-negligible amount of time. We
// may want to yield control of the main thread, so the browser can perform
// high priority tasks. The main ones are painting and user input. If there's
// a pending paint or a pending input, then we should yield. But if there's
// neither, then we can yield less often while remaining responsive. We'll
// eventually yield regardless, since there could be a pending paint that
// wasn't accompanied by a call to `requestPaint`, or other main thread tasks
// like network events.

if (enableIsInputPending) {
if (needsPaint) {
// There's a pending paint (signaled by `requestPaint`). Yield now.
return true;
}

if (timeElapsed < continuousInputInterval) {
// We haven't blocked the thread for that long. Only yield if there's a
// pending discrete input (e.g. click). It's OK if there's pending
// continuous input (e.g. mouseover).
if (isInputPending !== null) {
return isInputPending();
}
} else if (timeElapsed < maxInterval) {
// Yield if there's either a pending discrete or continuous input.
if (isInputPending !== null) {
return isInputPending(continuousOptions);
}
} else {
// We've blocked the thread for a long time. Even if there's no pending
// input, there may be some other scheduled work that we don't know about,
// like a network event. Yield now.
return true;
}
} // `isInputPending` isn't available. Yield now.
} // Yield now.

return true;
}

function requestPaint() {
if (
enableIsInputPending &&
navigator !== undefined && // $FlowFixMe[prop-missing]
navigator.scheduling !== undefined && // $FlowFixMe[incompatible-type]
navigator.scheduling.isInputPending !== undefined
) {
needsPaint = true;
} // Since we yield every frame regardless, `requestPaint` has no effect.
}
function requestPaint() {}

function forceFrameRate(fps) {
if (fps < 0 || fps > 125) {
Expand Down Expand Up @@ -788,10 +728,7 @@ if (__DEV__) {
isMessageLoopRunning = false;
}
}
} // Yielding to the browser will give it a chance to paint, so we can
// reset this.

needsPaint = false;
}
};

var schedulePerformWorkUntilDeadline;
Expand Down
44 changes: 7 additions & 37 deletions compiled/facebook-www/Scheduler-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@
var dynamicFeatureFlags = require("SchedulerFeatureFlags"),
userBlockingPriorityTimeout = dynamicFeatureFlags.userBlockingPriorityTimeout,
normalPriorityTimeout = dynamicFeatureFlags.normalPriorityTimeout,
lowPriorityTimeout = dynamicFeatureFlags.lowPriorityTimeout,
enableIsInputPending = dynamicFeatureFlags.enableIsInputPending,
enableIsInputPendingContinuous =
dynamicFeatureFlags.enableIsInputPendingContinuous,
frameYieldMs = dynamicFeatureFlags.frameYieldMs,
continuousYieldMs = dynamicFeatureFlags.continuousYieldMs,
maxYieldMs = dynamicFeatureFlags.maxYieldMs;
lowPriorityTimeout = dynamicFeatureFlags.lowPriorityTimeout;
function push(heap, node) {
var index = heap.length;
heap.push(node);
Expand Down Expand Up @@ -93,14 +87,7 @@ var taskQueue = [],
isHostTimeoutScheduled = !1,
localSetTimeout = "function" === typeof setTimeout ? setTimeout : null,
localClearTimeout = "function" === typeof clearTimeout ? clearTimeout : null,
localSetImmediate = "undefined" !== typeof setImmediate ? setImmediate : null,
isInputPending =
"undefined" !== typeof navigator &&
void 0 !== navigator.scheduling &&
void 0 !== navigator.scheduling.isInputPending
? navigator.scheduling.isInputPending.bind(navigator.scheduling)
: null,
continuousOptions = { includeContinuous: enableIsInputPendingContinuous };
localSetImmediate = "undefined" !== typeof setImmediate ? setImmediate : null;
function advanceTimers(currentTime) {
for (var timer = peek(timerQueue); null !== timer; ) {
if (null === timer.callback) pop(timerQueue);
Expand All @@ -126,20 +113,10 @@ function handleTimeout(currentTime) {
}
var isMessageLoopRunning = !1,
taskTimeoutID = -1,
frameInterval = frameYieldMs,
startTime = -1,
needsPaint = !1;
frameInterval = 10,
startTime = -1;
function shouldYieldToHost() {
var timeElapsed = exports.unstable_now() - startTime;
if (timeElapsed < frameInterval) return !1;
if (enableIsInputPending) {
if (needsPaint) return !0;
if (timeElapsed < continuousYieldMs) {
if (null !== isInputPending) return isInputPending();
} else if (timeElapsed < maxYieldMs && null !== isInputPending)
return isInputPending(continuousOptions);
}
return !0;
return exports.unstable_now() - startTime < frameInterval ? !1 : !0;
}
function performWorkUntilDeadline() {
if (isMessageLoopRunning) {
Expand Down Expand Up @@ -212,7 +189,6 @@ function performWorkUntilDeadline() {
: (isMessageLoopRunning = !1);
}
}
needsPaint = !1;
}
var schedulePerformWorkUntilDeadline;
if ("function" === typeof localSetImmediate)
Expand Down Expand Up @@ -259,7 +235,7 @@ exports.unstable_forceFrameRate = function (fps) {
? console.error(
"forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"
)
: (frameInterval = 0 < fps ? Math.floor(1e3 / fps) : frameYieldMs);
: (frameInterval = 0 < fps ? Math.floor(1e3 / fps) : 10);
};
exports.unstable_getCurrentPriorityLevel = function () {
return currentPriorityLevel;
Expand Down Expand Up @@ -288,13 +264,7 @@ exports.unstable_next = function (eventHandler) {
exports.unstable_pauseExecution = function () {
isSchedulerPaused = !0;
};
exports.unstable_requestPaint = function () {
enableIsInputPending &&
void 0 !== navigator &&
void 0 !== navigator.scheduling &&
void 0 !== navigator.scheduling.isInputPending &&
(needsPaint = !0);
};
exports.unstable_requestPaint = function () {};
exports.unstable_runWithPriority = function (priorityLevel, eventHandler) {
switch (priorityLevel) {
case 1:
Expand Down
Loading

0 comments on commit 9509de9

Please sign in to comment.