Skip to content
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

interval(0, animationFrameScheduler) emits twice each frame #4972

Closed
waterplea opened this issue Aug 20, 2019 · 7 comments
Closed

interval(0, animationFrameScheduler) emits twice each frame #4972

waterplea opened this issue Aug 20, 2019 · 7 comments
Labels
bug Confirmed bug

Comments

@waterplea
Copy link

waterplea commented Aug 20, 2019

Bug Report

Current Behavior
Currently, there seems to be 2 similar ways to organize requestAnimationFrame based observables:

  1. interval(0, animationFrameScheduler)
  2. of(0, animationFrameScheduler).pipe(repeat())

However first approach, using interval apparently emits twice each frame. See demo on Stackblitz.

Reproduction

Expected behavior
interval(0, animationFrameScheduler) should emit once each frame

Environment

  • Runtime: Chrome v76
  • RxJS version: 6.5.2

Additional context/Screenshots
Found those two solutions through search on StackOverflow:
https://stackoverflow.com/a/41818876/2706426

@martinsik
Copy link
Contributor

It looks more like this is an implementation detail (maybe how the internal browser's timer is refreshed) so it just appears like the events are duplicated. If you use a different method to measure the time between two emissions (new Date().getTime() - start) / duration you can see that the delays are different. Also for interval it makes on my machine around 120 emissions and only some of them have same times. With of it makes just around 50 emissions.

@waterplea
Copy link
Author

waterplea commented Sep 16, 2019

This is misleading then. requestAnimationFrame is capped at 60 frames per second as far as I know. Seems like interval(0, animationFrameScheduler) is not requestAnimationFrame at all. This is pretty important since it's totally different thing to do something with requestAnimationFrame and with interval every 16 milliseconds. Can somebody from rxjs team confirm how to properly make Observable of requestAnimationFrame?

@cartant
Copy link
Collaborator

cartant commented Sep 16, 2019

FWIW, the animationFrameScheduler definitely uses rAF:

return scheduler.scheduled || (scheduler.scheduled = requestAnimationFrame(
() => scheduler.flush(null)));

I've not yet had the time to look at the repro - or at Martin's analysis/comments - but I will try to find the time soon.

@cartant cartant added the bug Confirmed bug label Sep 16, 2019
@dominique-mueller
Copy link

I can confirm the issue, for each frame the observable emits twice. Very confusing, and certainly different from what I was expecting ...

@waterplea
Copy link
Author

Just came here to let you know that scheduled which is a suggested replacement to of with scheduler works fine emitting just once per frame. By the way, why animationFrameScheduler.now() returns a whole number timestamp whereas performance.now() has nanoseconds? I expected them to be equal, tbh.

@Achilles1515
Copy link

Achilles1515 commented Apr 19, 2020

Just came here to let you know that scheduled which is a suggested replacement to of with scheduler works fine emitting just once per frame.

Can you give an example of the proper way to do this?

See this StackBlitz (with the scheduled method being "third").

None of these counts using RxJS match up with the real requestAnimationFrame count (see the console logs). Am I doing something wrong with the scheduled example?

@waterplea
Copy link
Author

Yep, this is really strange. I haven't checked it the way you did, just the basic notion that there were 60 not 120 console logs per second gave me that impression.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Confirmed bug
Projects
None yet
Development

No branches or pull requests

5 participants