Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Safari and requestAnimationFrame gets DOMHighResTimestamp; window.performance not available

Ask Question

I created an animation using requestAnimationFrame . Works fine in Windows Chrome and IE; Safari (tested Safari 6 and 7) breaks. It turns out that rAF get a DOMHighResTimestamp rather than a Date timestamp. That's all fine and good, and what I expected, as it's now part of the spec. However, as far as I've been able to find, there's no way to get the current DOMHighResTimestamp (i.e. window.performance is not available, even with a prefix). So if I create the start time as a Date timestamp, it behaves radically wrong when I try to determine progress within the rAF callback (very small negative numbers).

If you look at this JSBin on Safari, it won't animate at all.

In this JBin, I've made a change to "skip" the first frame (where the time parameter is undefined ), so that startTime gets set to the time parameter on the next frame. Seems to work, but skipping a frame seems a bit crappy.

Is there some way to get the current DOMHighResTimestamp in Safari, given the lack of window.performance ? Or alternately, force rAF into some sort of legacy mode that forces it to get a Date timestamp instead?

Does anyone know why Safari has this inconsistency, where it provides the parameter in a format that you can't get at any other way?

Performance.now() is only a recommendation as of now. https://developer.mozilla.org/en-US/docs/Web/API/Performance.now() I can only assume it's a matter of time before it's official, seeing as how everyone but Safari has it built in.

Besides that fact use this to your advantage. Since you know requestAnimationFrame returns a DOMHighResTimestamp use that for your timing.

Game.start = function(timestamp){
    if(timestamp){
        this.time = timestamp;
        requestAnimationFrame(Game.loop);
    }else{
        requestAnimationFrame(Game.start);
Game.loop = function(timestamp){
    Game.tick(timestamp);
    ... your code
    requestAnimationFrame(Game.loop);
Game.tick = function(timestamp) {
    this.delta      = timestamp - this.time;
    this.time       = timestamp;

What I do here, is call Game.start which will begin the loop (I've run into situations where the timestamp was undefined so we try until we get something valid). Once we get that we have our base time and since RAF is going to return a timestamp our tick function never has to call Date.now or performance.now as long as we pass it the timestamp returned by requestAnimationFrame.

That looks like basically the same approach as my second JSBin--drop the first frame and start the animation on the second frame. It works, but doesn't really answer my question as to why Safari doesn't provide any way to access a DOMHighResTimestamp outside of rAF. – Turner Hayes Apr 26, 2014 at 22:40 That's just something they haven't implemented. I'm sure at some point they will, but for now save yourself the computations and use the one passed to you. – ericjbasti Apr 26, 2014 at 23:25 So I'm not missing anything--they really don't give access to DOMHighResTimestamp outside of the rAF callback? – Turner Hayes May 5, 2014 at 13:58 So I did a little more digging just to verify. Found this webkit.org/blog/2188/…, if you read the last paragraph you would think "The vendor prefix of window.performance.now() has been removed." would mean you could use it in Safari. However all other documentation states that the performance object does not exist in Safari and I can verify that it does not exist in the latest Safari. – ericjbasti May 6, 2014 at 2:01

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.