-
Notifications
You must be signed in to change notification settings - Fork 46.9k
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] Eagerly schedule rAF at beginning of frame #13785
Conversation
Should we add a more aggressive manual testing fixture? |
I don't understand what this changes. |
It's to defend against the browser pushing our animation callback into the frame after the next one, by scheduling it as early as possible. Eagerly, even before we know whether we need another frame to do work in or not. Can't think of a good fixture to simulate getting pushed into the next frame because it's so timing dependent. |
I suppose function animate() {
sleep(12); // or some number that will push us into next frame if scheduled too late
requestAnimationFrame(animate);
}
requestAnimationFrame(animate); and then mounting a bunch of slow components and measuring the overall time might work. I'll try it. |
React: size: 🔺+0.3%, gzip: 🔺+0.4% Details of bundled changes.Comparing: e2e7cb9...f92bbaa react
scheduler
Generated by 🚫 dangerJS |
5d38d58
to
0699ef3
Compare
let startOfLatestFrame = Date.now(); | ||
let currentTime = Date.now(); | ||
let startOfLatestFrame = 0; | ||
let currentTime = 0; |
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 is to make debugging easier. These tests use overridden Date.now()
so the start time is unimportant.
I'm a little confused here to use If I'm wrong, please let me know, thanks! |
requestAnimationFrameWithTimeout(animationTick); | ||
} else { | ||
// No pending work. Exit. | ||
isAnimationFrameScheduled = false; |
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.
We can now unify these checks so we can get rid of this flag and just use scheduledCallback
as the flag.
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.
I thought this would work but now I don't think it does. There are three callbacks: the one scheduled with requestAnimationFrame
(represented by isAnimationFrameScheduled
), the message
event handler (represented by isIdleScheduled
), and the one that actually contains the work (scheduledCallback
). Need all three concepts. For example, as added by this PR, sometimes an animation frame is scheduled even if there's no actual work scheduled. So I think all three are needed.
I'll rename these a bit so it's less confusing.
Eagerly schedule the next animation callback at the beginning of the frame. If the scheduler queue is not empty at the end of the frame, it will continue flushing inside that callback. If the queue *is* empty, then it will exit immediately. Posting the callback at the start of the frame ensures it's fired within the earliest possible frame. If we waited until the end of the frame to post the callback, we risk the browser skipping a frame and not firing the callback until the frame after that.
0699ef3
to
2352424
Compare
2352424
to
f92bbaa
Compare
* [scheduler] Eagerly schedule rAF at beginning of frame Eagerly schedule the next animation callback at the beginning of the frame. If the scheduler queue is not empty at the end of the frame, it will continue flushing inside that callback. If the queue *is* empty, then it will exit immediately. Posting the callback at the start of the frame ensures it's fired within the earliest possible frame. If we waited until the end of the frame to post the callback, we risk the browser skipping a frame and not firing the callback until the frame after that. * Re-name scheduledCallback -> scheduledHostCallback
* [scheduler] Eagerly schedule rAF at beginning of frame Eagerly schedule the next animation callback at the beginning of the frame. If the scheduler queue is not empty at the end of the frame, it will continue flushing inside that callback. If the queue *is* empty, then it will exit immediately. Posting the callback at the start of the frame ensures it's fired within the earliest possible frame. If we waited until the end of the frame to post the callback, we risk the browser skipping a frame and not firing the callback until the frame after that. * Re-name scheduledCallback -> scheduledHostCallback
Eagerly schedule the next animation callback at the beginning of the frame. If the scheduler queue is not empty at the end of the frame, it will continue flushing inside that callback. If the queue is empty, then it will exit immediately. Posting the callback at the start of the frame ensures it's fired within the earliest possible frame. If we waited until the end of the frame to post the callback, we risk the browser skipping a frame and not firing the callback until the frame after that.