Inconsistent delta when using requestAnimationFrame and Date.now()

I have a simple snippet:

let startTime = -1
let lastNow = -1
let lastTS = -1
const animate = (timeStamp)=>{
  requestAnimationFrame(animate)
  const now = Date.now()
  if(lastTS===-1){
    lastTS = timeStamp
    lastDate = now
  }
  const deltaTS = timeStamp - lastTS
  lastTS = timeStamp
  const deltaNow = now - lastNow
  lastNow = now
  console.log(deltaTS,deltaNow)
}

animate(-1)

And I see what i expect, the values are somewhat similar, with the timestamp being much more precise

enter image description here

But, when using this exact code in a massive code base, i see wildly inconsistent results. The delta derived from raf’s timestamp is consistent with my refresh rate, the one comparing two Date.now() calls varies between 4 and a lot. What could possibly be causing this? I suspect i may have animate(-) firing a few times, but i still don’t understand why would these be so oddly spaced out.

>Solution :

The timestamp passed to the callback of requestAnimationFrame is, in Chrome and Firefox at least, the time of the last V-Sync signal and in the specs, the time of the beginning of the rendering frame.

All callbacks in the same rendering frame will share the same timestamp.

So what you see here is probably just that your own callback fires after some heavy ones:

requestAnimationFrame((ts) => {
  const now = performance.now();
  const diff = now - ts;
  console.log("first callback", { ts, now, diff });
  while(performance.now() - now < 200) {
    // block the event-loop 200ms
  }
});
requestAnimationFrame((ts) => {
  const now = performance.now();
  const diff = now - ts;
  console.log("second callback", { ts, now, diff });
});

Leave a Reply