-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Stop RAF update loop when there are no pending tasks #1786
Conversation
Update "Transitioning between routes" example to use latest React Router syntax
Co-authored-by: Josh <37798644+joshuaellis@users.noreply.github.com>
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/pmndrs/react-spring-io/4Yzat6kRQJVL4VnzBrjvCG4wb1Vd |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 6ada3cf:
|
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.
Just a few questions for my own understanding. But overall it looks great!
@@ -201,7 +212,13 @@ function eachSafely<T>(values: Eachable<T>, each: (value: T) => void) { | |||
/** Tree-shakable state for testing purposes */ | |||
export const __raf = { | |||
/** The number of pending tasks */ | |||
count: 0, | |||
count(): number { |
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.
It'd be helpful for me to understand why we've moved count
to a pseudo getter
function with a global variable.
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.
My understanding from the comments is that __raf
is intended to be a container for data/functions that are used only in the tests. As of this PR, the count
variable is now needed for actual control flow rather than just for test observability, so I moved it to a global.
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.
Will release this in the upcoming 9.4.0 (it'll be released on beta later today). Thank you again!
No problem, and thank you for the quick merge! |
* fix(radar): improve radar's legend data to be customizable * fix(radar): add unit test case and stories * fix(rader): fix bounded legend data generate bug and apply memoizing * fix(rader): fix bounded legend data to have a color default value
Why
A quick test in Chrome shows that a no-op requestAnimationFrame update loop idles between 5-10% CPU usage (codesandbox).
@react-spring/rafz and react-spring are susceptible to this behavior: once a task is scheduled with rafz, the update loop never stops even if there is never any other work scheduled. See this bug, which shows an example of this issue: #1732
What
This PR stops the raf update loop if there are no pending tasks. It does so using a task counting variable that was already present in the code but only used for testing. I added unit tests to verify that the update loop is running when necessary and stopped when able.
I also ran the code sample from #1732 (and on another codebase) with this code change and verified that the raf update loop is not running indefinitely:
(left, before hitting "Destroy AnimationComponent"; right: after hitting "Destroy AnimationComponent")
I could use some guidance as to how to verify that this change is not negatively impacting or regressing anything else in the library.
Checklist