0
\$\begingroup\$

I have an event listener in JavaScript looking for keydown events.

document.addEventListener('keydown', e => {
    // Callback code
});

What is the latency between someone pressing a key and my function executing. Is the function immediately added to the event queue or does it wait until the next frame is ready to be drawn? Is the behavior consistent between web browsers?

Just to be extra clear, I'm only interested latency in the context of web browsers, not anything before it.

\$\endgroup\$
1
\$\begingroup\$

The JS engine of the web browser operates in a single thread and has a task queue which operates on the first-come-first-served principle. That means anytime an event occurs, that event is pushed to the end of the task queue and gets acted upon as soon as everything that happened before was executed completely.

requestAnimationFrame tells the web browser to run a function on the next repaint-event. Repaint-events are generated constantly by the browsers rendering engine. Pressing a key also generates an event - a keydown-event. So whether the keydown-event gets processed before or after the next repaint-event depends on whether or not a repaint-event is already in the queue and waiting to be executed.

For more information on how events in JS are handled under the hood, I recommend this article: Understanding JavaScript Call Stack, Task Queue and Event Loop

\$\endgroup\$
3
  • \$\begingroup\$ Thanks for the answer and link. I think it doesn't quite answer my question though, so I'll do my best to explain further. I remember reading somewhere (I can't find the link) that a browser will wait until the next repaint to add callbacks from input events to the event queue. I was wondering if it does wait or if it immediately adds the function the event to the queue without waiting. \$\endgroup\$
    – Dan
    Feb 4 at 15:36
  • \$\begingroup\$ @Dan I don't know where you read that, but my understanding is that keydown events should get pushed to the queue immediately, and when there is no repaint-event already queued they should also get executed before the next repaint-event. \$\endgroup\$
    – Philipp
    Feb 4 at 15:41
  • \$\begingroup\$ I wrote some code to test that tests that and I believe you are right. My monitor is set to 60hz and I'm getting the callback at 11ms on average. document.addEventListener('click', e => { console.log(performance.now()); }); var lastTime = performance.now(); setInterval(() => { if (performance.now() - lastTime >= 1000/120) { document.querySelector('body').click(); lastTime = performance.now(); } }); \$\endgroup\$
    – Dan
    Feb 4 at 16:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.