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

use monotonic clock for elapsed time #5870

Merged
merged 22 commits into from
Apr 24, 2019
Merged

Conversation

thijstriemstra
Copy link
Contributor

@thijstriemstra thijstriemstra commented Mar 18, 2019

Description

Improve accuracy using performance.now()

See https://developers.google.com/web/updates/2012/08/When-milliseconds-are-not-enough-performance-now

Specific Changes proposed

All major browsers support this for ages, although IE supports it since v10, according to https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

@thijstriemstra thijstriemstra changed the title use monotonic clock in util.fn.throttle use monotonic clock Mar 18, 2019
@thijstriemstra
Copy link
Contributor Author

thijstriemstra commented Mar 18, 2019

Not sure what this error is about: https://travis-ci.org/videojs/video.js/builds/507654239#L295 Some vjsstandard thing?

@brandonocasey
Copy link
Contributor

To get around the vjsstandard linter issue you will want to use window.performance.now() rather than just performance.now(). Although based on the benchmarks that I see on jsperf you may want to do const performance = window.performance; at the top of the file and just keep the code how it is.

I also see that we use Date in two others places that may also need to be changed:
https://github.com/videojs/video.js/blob/master/src/js/utils/dom-data.js#L26
https://github.com/videojs/video.js/blob/master/src/js/tech/html5.js#L868

After looking into this a bit it seems like performance.now() is slower performance wise: https://jsperf.com/new-date-vs-date-now-vs-performance-now/6

It also looks like Google recommends using performance.now: https://developers.google.com/web/tools/lighthouse/audits/date-now

@gkatsev
Copy link
Member

gkatsev commented Mar 28, 2019

I doubt that anywhere we use it, we really have any performance implications to using Date.now() vs new Date().getTime() vs performance.now().
Looks like IE11 has performance.now()? Should be safe to update then.

@thijstriemstra
Copy link
Contributor Author

thijstriemstra commented Mar 29, 2019

we really have any performance implications

Agreed, the term performance(.now) is a little misleading to me, the actual improvement is a consistent clock (that does not adjust at any time, unlike Date.getTime).

I also see that we use Date in two others places that may also need to be changed:

Will take a look. Thanks for the review.

@thijstriemstra
Copy link
Contributor Author

Another mysterious failure: https://travis-ci.org/videojs/video.js/builds/513188217#L432

@gkatsev
Copy link
Member

gkatsev commented Mar 29, 2019

Looks like the test that's failing is the node require test. Looks like one of the usages of window.performance is being run directly on require and it's crashing. We should either do null checks and fallback to Date.now() or potentially just not do anything if it doesn't exist. It should basically just not throw any errors in a node require rather than have to work.

@thijstriemstra
Copy link
Contributor Author

Should I just revert the changes in src/js/tech/html5.js?

@brandonocasey
Copy link
Contributor

brandonocasey commented Apr 23, 2019

OK, so I looked into the travis issue and it is related to the change in dom-data and the require in node test. It fails because we cannot use window.performance in node since node does not have a window and performance is not a global. Node exports performance in perf_hooks. Perhaps for now we should revert the change in that file, as there doesn't seem to be an easy way to deal with it.

EDIT:
Actually I found a way, we could do it for now.
Add a now definition at the top of dom-data and then use that instead of window.performance.now

EX:

const now = (window.performance && window.performance.now && window.performance.now()) || Date.now();

...
const elIdAttr = 'vdata' + Math.floor(now);

@thijstriemstra
Copy link
Contributor Author

Add a now definition at the top of dom-data and then use that instead of window.performance.now

will do.

@thijstriemstra
Copy link
Contributor Author

Made changes, up for review.

src/js/utils/dom-data.js Outdated Show resolved Hide resolved
@gkatsev
Copy link
Member

gkatsev commented Apr 23, 2019

ooh, good call

Copy link
Contributor

@brandonocasey brandonocasey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think anyone should rely on vdata_ and if they do they should be using something like vdata_\d+ to find it. I don't have any concerns with this change.

@thijstriemstra
Copy link
Contributor Author

with this sinon stub in place, a change in src/js/tech/html5.js should be testable as well right?

@thijstriemstra
Copy link
Contributor Author

with this sinon stub in place, a change in src/js/tech/html5.js should be testable as well right?

it actually seems the stub isn't initialized properly when moving it to the global-shims module.. any idea?

@gkatsev
Copy link
Member

gkatsev commented Apr 23, 2019

the stub in global-shim may be happening to early, it may be necessarily to do after every usage of useFakeTimers.
Looks like we may want to update our version of sinon finally since it seems a newer version of lolex the underlying fake timers lib stubs out performance.

@thijstriemstra
Copy link
Contributor Author

Looks like we may want to update our version of sinon

sounds good.

@thijstriemstra
Copy link
Contributor Author

Can you update sinon in the master branch?

@gkatsev
Copy link
Member

gkatsev commented Apr 23, 2019

if you use npm 6, it should update the package-lock file as well, you'd want to check it in. But yeah, we can take a look at updating sinon in a separate PR as it's possible things will break.

@thijstriemstra
Copy link
Contributor Author

thijstriemstra commented Apr 23, 2019

updating sinon in a separate PR as it's possible things will break.

I've opened #5953 for this. We shouldn't add workarounds for testing in prod code, but simply make sure the test env is setup properly.

@thijstriemstra thijstriemstra changed the title use monotonic clock use monotonic clock for calculating elapsed time Apr 23, 2019
@thijstriemstra thijstriemstra changed the title use monotonic clock for calculating elapsed time use monotonic clock for elapsed time Apr 23, 2019
@gkatsev
Copy link
Member

gkatsev commented Apr 24, 2019

@thijstriemstra I updated sinon in #5954 which is now in master, if you rebase/merge in master, it should fix the build.

@gkatsev
Copy link
Member

gkatsev commented Apr 24, 2019

Not sure what's up with netlify, but it isn't actually required to pass.

@thijstriemstra
Copy link
Contributor Author

Ready for review.

@gkatsev gkatsev merged commit 629594e into videojs:master Apr 24, 2019
@gkatsev
Copy link
Member

gkatsev commented Apr 24, 2019

Thanks @thijstriemstra!

@thijstriemstra thijstriemstra deleted the patch-4 branch January 25, 2021 23:18
@fermarci
Copy link

Hi, The usage performance.now is not "secure" in all occurrences.

In html5.js and dom-data.js it is fine.
But in:
fn.js -
64. let last = window.performance.now();
67. const now = window.performance.now();
live-tracker.js -
96. const newTime = Number(window.performance.now().toFixed(4));
components.js -
1221. touchStart = window.performance.now();
1259. const touchTime = window.performance.now() - touchStart;

in systems where Performance API is not available it will generate an error.

would be nice to fix this.

@thijstriemstra
Copy link
Contributor Author

in systems where Performance API is not available

Which ones?

@fermarci
Copy link

Hi, we had problems on older LG and Samsung TV sets.

@thijstriemstra
Copy link
Contributor Author

@fermarci you can use a polyfill for these devices: https://gist.github.com/paulirish/5438650#gistcomment-2976364

@mister-ben mister-ben mentioned this pull request Aug 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants