1

In a previous post, timing inconsistencies using requestAnimationFrame were suggested to be solved with an infinite requestAnimationFrame loop e.g. as follows.

function workaroundLoop() {
  requestAnimationFrame(workaroundLoop);
};

I actually tested this with an oscilloscope, and this looping does nicely improve timing precision in all browsers (not only Chrome, as suggested in that post).

The new problem however is that it introduces a 1-frame delay in changing the display (when a command for that is given). For example, if the line document.getElementById('stimulus_id').textContent = "NEW DISPLAY"; is executed, the text "NEW DISPLAY" will not be displayed in the upcoming repaint of the screen, but only in the following one. So, if there is no looping, the painting is always immediate and follows the command within 0-16 ms (given the 60Hz refresh rate), but if the loop is going on, the painting always gets delayed and only happens 16-32 ms following the command.

Remarkably, if I use canvas with desynchronized: true for the display, there is no delay in Chrome, Microsoft Edge, Opera, but there is still a delay in Firefox. However, apart from that this does not work in Firefox, I would also not know how to use this solution for non-canvas display (such as simple text).

Any ideas about (a) why exactly this is happening and (b) how to solve this? That is: I still want to benefit of precise timing, but I also want to be able to display (paint) elements immediately.

gaspar
  • 898
  • 1
  • 13
  • 26
  • I already told you by email, but for the ones coming here, a few points I suspect where this could come from: depending on where you get the input time: USB delay ; delay between the USB packet reception and the actual execution of the task that will fire the event ; delay between the browser telling the OS's renderer to paint and the actual paint to monitor. It might also be something else entirely... – Kaiido Jul 25 '21 at 03:16
  • I checked the USB delay (external timing vs. JS keydown timing) across all methods, and it is extremely consistent (within 1-2 ms), so it cannot cause a whole frame delay. I cannot know for certain whether there is a delay between the browser's paint command and the actual paint time, but again any potential (and testable) solutions are welcome. – gaspar Jul 25 '21 at 08:16
  • 1
    Well you could try to measure the time it takes from a [desynchronized](https://html.spec.whatwg.org/multipage/canvas.html#dom-canvasrenderingcontext2dsettings-desynchronized) context vs a *normal* one to be painted to the screen from the same rAF callback. If you find out that indeed the *normal* one is painted about a frame later, we can probably assume that the browser's command is treated by the OS renderer only one frame later. – Kaiido Jul 25 '21 at 09:45
  • You are right, desynchronized context got rid of the delay in all browsers but in Firefox. I updated the question. – gaspar Jul 30 '21 at 14:33
  • 1
    Unfortunately I believe we just proved that the 1 frame delay is at the OS level. All rendering will usually go through that path, and I believe `desynchronized` is the first time Chromium used the "shortcuts" to draw to the monitor. So this is not a solution for your problem, desynchronized only works with canvas, in chromium based browsers, on Windows or ChromeOS. You won't have it on phones, nor mac nor linux. There is to my knowledge no other way though. Sorry. (Ps: you may want to let Fernando know about this, his knowledge his wider than mine) – Kaiido Jul 30 '21 at 14:44

0 Answers0