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

suggestion: mock performance.now() in FakeTime #4552

Open
jespertheend opened this issue Apr 7, 2024 · 8 comments
Open

suggestion: mock performance.now() in FakeTime #4552

jespertheend opened this issue Apr 7, 2024 · 8 comments
Labels
feedback welcome We want community's feedback on this issue or PR suggestion a suggestion yet to be agreed testing

Comments

@jespertheend
Copy link
Contributor

Is your feature request related to a problem? Please describe.

The FakeTime class only seems to mock things such as Date.now().

Describe the solution you'd like

To have it also mock performance.now().

Describe alternatives you've considered

I'm just mocking it myself right now but it's not pretty.

@iuioiua
Copy link
Collaborator

iuioiua commented Apr 8, 2024

Are you able to elaborate on your use case?

@iuioiua iuioiua changed the title FakeTime doesn't mock performance.now() suggestion: mock performance.now() in FakeTime Apr 8, 2024
@iuioiua iuioiua added testing suggestion a suggestion yet to be agreed feedback welcome We want community's feedback on this issue or PR labels Apr 8, 2024
@jespertheend
Copy link
Contributor Author

My use case is that I'm using performance.now() in many places instead of Date.now(). I'm not really sure why to be honest, I think it's an old relic from when performance.now() used to have higher precision than Date.now().

I was trying to write tests for code that was using performance.now() and planned on using FakeTime, thinking it would mock it. But that's when I found out it wasn't added yet.

@iuioiua
Copy link
Collaborator

iuioiua commented Apr 9, 2024

Let's consider your use case. Is its purpose to measure durations between multiple points in time? Does it need the higher precision of performance.now()? If the answer to both of these questions is yes, using performance.now() makes sense. If the answer to both is now, Date.now(), which already has the mocking utility, it makes more sense to use. I just want to ensure that the use case for mocking performance.now() is valid enough to justify having the mocking utility for it.

@jespertheend
Copy link
Contributor Author

In this case specifically I'm using performance.now() to compare the deltatime between two "wheel" events in order to determine how long the user has been scrolling. But I have also used performance.now() a lot in the past when computing the deltatime between two frames, or animating an object over time for example.

Aside from the higher precision, performance.now() is also more beneficial in these cases because these systems could get messed up when the system time changes.

@iuioiua
Copy link
Collaborator

iuioiua commented Apr 11, 2024

Ok. That sounds reasonable to me. @kt3k, WDYT? I misunderstood. I agree with Yoshiya's comment below.

@iuioiua iuioiua added the PR welcome A pull request for this issue would be welcome label Apr 11, 2024
@kt3k
Copy link
Member

kt3k commented Apr 11, 2024

perfomance.now() doesn't return unix timestamp, but it returns elapsed time from some random time origin. If FakeTime works with perfomance.now() in a similar way as Deno.now, that feels confusing to me.

Also higher precision time is disabled by default, and its usage is generally discouraged because of the security issues. I think there's no particular reason to encourage the use of performance.now()

@jespertheend
Copy link
Contributor Author

I looked some more into this and it seems like the precision of performance.now() is 100 microseconds nowadays. Which is still one order of magnitude more precise than Date.now().

As for discouraging/encouraging the use of performance.now(), it really depends on what you plan on using it for.
MDN puts it best:

Also, Date.now() may have been impacted by system and user clock adjustments, clock skew, etc. as it is relative to the Unix epoch (1970-01-01T00:00:00Z) and dependent on the system clock. The performance.now() method on the other hand is relative to the timeOrigin property which is a monotonic clock: its current time never decreases and isn't subject to adjustments.

FakeTime seems to suggest it affects all time related apis, including setTimeout, setInterval etc. So it was kind of surprising to me that performance.now() remained unaffected.

Although I agree including performance.now() might feel somewhat confusing. With most FakeTime methods I think it should be pretty clear. FakeTime.tick() for instance would move time forward for both Date.now() and performance.now(). The only two instances that seem confusing are getting/setting FakeTime.now and FakeTime.start, since these specifically seem related to system time.

@iuioiua iuioiua removed the PR welcome A pull request for this issue would be welcome label Apr 11, 2024
@kt3k
Copy link
Member

kt3k commented Apr 15, 2024

As for discouraging/encouraging the use of performance.now(), it really depends on what you plan on using it for. MDN puts it best:

Also, Date.now() may have been impacted by system and user clock adjustments, clock skew, etc. as it is relative to the Unix epoch (1970-01-01T00:00:00Z) and dependent on the system clock. The performance.now() method on the other hand is relative to the timeOrigin property which is a monotonic clock: its current time never decreases and isn't subject to adjustments.

If the point of performance.now() is being independent of system time, then I wonder if it's good idea to let FakeTime affect performance.now() as FakeTime simulates 'system time'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feedback welcome We want community's feedback on this issue or PR suggestion a suggestion yet to be agreed testing
Projects
None yet
Development

No branches or pull requests

3 participants