Colin Dumitru
Colin Dumitru

Reputation: 3455

Better way of getting time in milliseconds in javascript?

Is there an alternative in JavaScript of getting time in milliseconds using the date object, or at least a way to reuse that object, without having to instantiate a new object every time I need to get this value? I am asking this because I am trying to make a simple game engine in JavaScript, and when calculating the "delta frame time", I have to create a new Date object every frame. While I am not too worried about the performance implications of this, I am having some problems with the reliability of the exact time returned by this object.

I get some strange "jumping" in the animation, every second or so, and I am not sure if this is related to JavaScript's Garbage Collection or a limitation of the Date object when updating so fast. If I set the delta value to some constant, then the animation if perfectly smooth, so I am fairly sure this "jumping" is related to the way I get the time.

The only relevant code I can give is the way I calculate the delta time :

prevTime = curTime;
curTime = (new Date()).getTime();
deltaTime = curTime - prevTime;

When calculating movement / animation I multiply a constant value with the delta time.

If there is no way to avoid getting the time in milliseconds by using the Date object, would a function that increments a variable (being the elapsed time in milliseconds since the game started), and which is called using the SetTimer function at a rate of once every milliseconds be an efficient and reliable alternative?

Edit : I have tested now my code in different browsers and it seems that this "jump" is really only apparent in Chrome, not in Firefox. But it would still be nice if there were a method that worked in both browsers.

Upvotes: 172

Views: 231012

Answers (6)

Lauri
Lauri

Reputation: 201

Example above (https://stackoverflow.com/a/16081647/1593719) could be written this way. Note the .bind(..)

//@ts-nocheck
const performance = window.performance || {}
const now = (function () {
    const nowImpl =
        performance.now ||
        performance.mozNow ||
        performance.msNow ||
        performance.oNow ||
        performance.webkitNow
    return (nowImpl && nowImpl.bind(performance))
        || Date.now  /*none found - fallback to browser default */
})();

export default now

Upvotes: 0

Chris GW Green
Chris GW Green

Reputation: 1199

I know this is a pretty old thread, but to keep things up to date and more relevant, you can use the more accurate performance.now() functionality to get finer grain timing in javascript.

window.performance = window.performance || {};
performance.now = (function() {
    return performance.now       ||
        performance.mozNow    ||
        performance.msNow     ||
        performance.oNow      ||
        performance.webkitNow ||            
        Date.now  /*none found - fallback to browser default */
})();

Upvotes: 57

dilip kumar
dilip kumar

Reputation: 517

If you have date object like

var date = new Date('2017/12/03');

then there is inbuilt method in javascript for getting date in milliseconds format which is valueOf()

date.valueOf(); //1512239400000 in milliseconds format

Upvotes: 17

LarsKnudsen
LarsKnudsen

Reputation: 122

This is a very old question - but still for reference if others are looking at it - requestAnimationFrame() is the right way to handle animation in modern browsers:

UPDATE: The mozilla link shows how to do this - I didn't feel like repeating the text behind the link ;)

Upvotes: 4

ngryman
ngryman

Reputation: 7672

As far that I know you only can get time with Date.

Date.now is the solution but is not available everywhere : https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/now.

var currentTime = +new Date();

This gives you the current time in milliseconds.

For your jumps. If you compute interpolations correctly according to the delta frame time and you don't have some rounding number error, I bet for the garbage collector (GC).

If there is a lot of created temporary object in your loop, garbage collection has to lock the thread to make some cleanup and memory re-organization.

With Chrome you can see how much time the GC is spending in the Timeline panel.

EDIT: Since my answer, Date.now() should be considered as the best option as it is supported everywhere and on IE >= 9.

Upvotes: 61

Joeri Sebrechts
Joeri Sebrechts

Reputation: 11146

Try Date.now().

The skipping is most likely due to garbage collection. Typically garbage collection can be avoided by reusing variables as much as possible, but I can't say specifically what methods you can use to reduce garbage collection pauses.

Upvotes: 204

Related Questions