Why setTimeout Can Only Be Set to 4ms Minimum

How To Achieve 0ms setTimeout?

Danielle Dias
Geek Culture
3 min readApr 7, 2023

--

Photo by Thomas Bormans on Unsplash

If you’ve been working with JavaScript for a while, you’ve likely used the setTimeout() function to schedule a function to be executed after a certain amount of time. However, you may have noticed that the minimum delay you can specify with setTimeout() is 4 milliseconds (ms). But why is that? And is it possible to achieve a setTimeout() delay of 0ms?

Why setTimeout Can Only Be Set to 4ms Minimum

The reason why setTimeout can only be set to a minimum of 4ms is due to browser limitations. Browsers have an event loop that processes various tasks such as handling user input, updating the screen, and executing JavaScript code. When you use setTimeout, the browser adds your function to a queue of tasks that need to be executed in the future. The browser then waits for the specified amount of time before executing the function.

However, if the specified timeout is too short, the browser may not have enough time to process other tasks in the queue before executing your function. This can lead to a phenomenon called “starvation” where some tasks are never executed because the browser is too busy executing the short timeouts. To prevent this, browsers have a minimum timeout value of 4ms. This ensures that the browser has enough time to process other tasks before executing the next timeout.

Achieving 0ms setTimeout

While 4ms may not seem like a long time, it can be a significant delay for certain applications that require fast response times. In some cases, you may want to achieve a 0ms setTimeout to ensure that your code is executed as soon as possible. There are several techniques that can be used to achieve a 0ms setTimeout, each with its own advantages and disadvantages.

MessageChannel

MessageChannel is an API that allows you to communicate between different execution contexts in JavaScript. This API can also be used to achieve a 0ms setTimeout. Here’s an example:

function zeroTimeout(callback) {
const channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}

In this example, the zeroTimeout function creates a new MessageChannel and sets up a message event listener on port1. The callback function is then passed as the event listener. Finally, the function sends an empty message to port2, which triggers the message event on port1 and executes the callback function.

MutationObserver

MutationObserver is an API that allows you to observe changes to the DOM and execute a callback function when a change occurs. This API can also be used to achieve a 0ms setTimeout. Here’s an example:

function zeroTimeout(callback) {
const observer = new MutationObserver(callback);
const element = document.createElement('div');
observer.observe(element, { attributes: true });
element.setAttribute('id', 'zero-timeout');
}

In this example, the zeroTimeout function creates a new MutationObserver and sets up the callback function as the observer. The function also creates a new div element and observes changes to its attributes. Finally, the function sets the id attribute of the element to ‘zero-timeout’, which triggers the mutation observer and executes the callback function.

Web Workers

Web Workers are a feature of JavaScript that allows you to run scripts in the background without blocking the main thread. This feature can also be used to achieve a 0ms setTimeout. Here’s an example:

function zeroTimeout(callback) {
const worker = new Worker(URL.createObjectURL(
new Blob([`setTimeout(() => postMessage(''), 0);`])
));

worker.onmessage = callback;
}

Conclusion

In this article, we discussed the reasons behind the minimum delay of 4 milliseconds in setTimeout(), and gave several implementation ideas. As far as I know, these solutions are not perfect, and you can test them according to your needs. Hope it helps you.

Thanks for reading. If you enjoyed this article, consider supporting me by becoming a Medium member.

--

--