DEV Community

Cover image for Why you can't trust setTimeout
Shuvo
Shuvo

Posted on

6

Why you can't trust setTimeout

setTimeout in JavaScript takes time in millisecond so it must be very accurate right?

Well not necessarily. In this article let's explore why.

We all know that JavaScript is single-threaded. Meaning that it can only calculate one thing at a time.
But now imagine you have a setTimeout that is suppose to fire after 10000ms or 10s. So now JS have to keep track of the time passed. But in between that 10s the user might do some interaction with your page. Now JavaScript have to react to them as well.

But if JavaScript is single threaded how it's gonna keep track of passed time while reacting to user activity? That would be performing multiple calculation at the same time right?
Well not really because JavaScript is not keeping track of time. In fact JavaScript doesn't natively support setTimeout even. Then how are we able to use setTimeout? Well these special asynchronous functions like setTimeout, setInterval are provided to JS by the environment it is currently running on. For example in case of Chrome JavaScript runs on the V8 engine, and Fire Fox uses SpiderMonkey as its JavaScript engine etc.

So basically when you call setTimeout, JavaScript under the hood tells its environment/the engine its running on that once all the synchronous code is done executing set a timer and once the timer reaches the given time execute the function.
Now notice that I said "once all the synchronous code is done executing". And this is where the problem lives. The timer for setTimeout won't start until all the normal synchronous codes like dom manipulations, loops etc. aren't fully executed.
And those synchronous codes might take some time to execute.
Here's a dummy code that takes couple of milliseconds to execute.

//JS hack: +new Date() will give you current time in milliseconds 😉
let currentTime = +new Date()
//Dummy long loop
for(let i = 0; i < 999999999; i++){}
//Current time after the loop is over
let endTime = +new Date()
console.log("Ran after: " + (endTime - currentTime) + "ms")
Enter fullscreen mode Exit fullscreen mode

JavaScript get code execution time
And so if we had a setTimeout out in our code that is suppose to run after lets say 50ms, it might run a few milliseconds late

let currentTime = +new Date()
setTimeout(function(){
    let endTime = +new Date()
    console.log("Ran after: " + (endTime - currentTime) + "ms")
}, 50)
for(let i = 0; i < 99999999; i++){

}
Enter fullscreen mode Exit fullscreen mode

JS setTimeout running late

Conclusion

Although setTimeout is fine to use most of the time, but for very time sensitive task it might not be the ideal choice

Make sure you checkout my other articles and YouTube channel

Was it helpful? Support me on Patreon

Patreon Logo

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (2)

Collapse
 
mrvabs profile image
Vaibhav

Very useful 👍

Collapse
 
0shuvo0 profile image
Shuvo

Thanks 💓

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay