-
Notifications
You must be signed in to change notification settings - Fork 47k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Scheduler] Test browser implementation details #16198
Conversation
The Scheduler implementation uses browser APIs like `MessageChannel`, `requestAnimationFrame`, and `setTimeout` to schedule work on the main thread. Most of our tests treat these as implementation details; however, the sequence and timing of these APIs are not precisely specified, and can vary wildly across browsers. To prevent regressions, we need the ability to simulate specific edge cases that we may encounter in various browsers. This adds a new test suite that mocks all browser methods used in our implementation. It assumes as little as possible about the order and timing of events. The only thing it assumes is that requestAnimationFrame is passed a frame time that is equal to or less than the time returned by performance.now. Everything else can be controlled at will. It also includes Scheduler-specific invariants, e.g. only one rAF callback can be scheduled at a time. It overlaps slightly with the existing SchedulerDOM-test suite, which also mocks the browser APIs, but exposes a higher-level set of testing primitives. I will consolidate the two suites in a follow-up.
prevRAFTime !== -1 && | ||
// Make sure this rAF time is different from the previous one. This check | ||
// could fail if two rAFs fire in the same frame. | ||
rAFTime - prevRAFTime > 0.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This particular change fixes a bug in Safari where we post a rAF from inside another rAF, and that rAF fires within the same frame. One of the tests I added covers this scenario.
React: size: -0.0%, gzip: -0.0% Details of bundled changes.Comparing: 19354db...8c1adfa react
scheduler
Generated by 🚫 dangerJS |
f0b0bcd
to
8c1adfa
Compare
currentTime = targetTime; | ||
} | ||
} | ||
function getMostRecentFrameNumber() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trivial naming nit: getCurrentFrameNumber
? "Most recent" feels like an odd name to use when currentTime
is exactly at a frame boundary.
Edit I see how you're using this method in the tests below, and getMostRecentFrameNumber
makes more sense as a name. I think the usage in fireAnimationFrame
feels more like a "current" value but I don't feel strongly about this. 😄
The Scheduler implementation uses browser APIs like
MessageChannel
,requestAnimationFrame
, andsetTimeout
to schedule work on the main thread. Most of our tests treat these as implementation details; however, the sequence and timing of these APIs are not precisely specified, and can vary wildly across browsers.To prevent regressions, we need the ability to simulate specific edge cases that we may encounter in various browsers.
This adds a new test suite that mocks all browser methods used in our implementation. It assumes as little as possible about the order and timing of events. The only thing it assumes is that requestAnimationFrame is passed a frame time that is equal to or less than the time returned by performance.now. Everything else can be controlled at will.
It also includes Scheduler-specific invariants, e.g. only one rAF callback can be scheduled at a time.
It overlaps slightly with the existing SchedulerDOM-test suite, which also mocks the browser APIs, but exposes a higher-level set of testing primitives. I will consolidate the two suites in a follow-up.