Question: How to know which events slow down `setTimeout()`?

In my code I have a keyframe animation of 2 seconds.

I add a class to animate a div

```
$('#first').addClass('first-start');

```

and using `setTimeout` I add a class to stop the animation only after 1 second.

```
setTimeout(function() {
    $('#first').addClass('first-pause');
}, 1000);

```

All animation should be of 2 seconds if I don't block it.

I noticed that `setTimeout` sometimes not run exactly after 1000 milliseconds.
How can I solve this?

How can I know which events slow down `setTimeout`?

Answer: 
JavaScript timers are very inaccurate and there is nothing you can do about it. The timers only fire up if both of the following are met:

* The Execution Stack of the currently active queued event is empty
* The timer has elapsed

The key insight to grasping why is it so is understanding that JavaScript is single-threaded by specification (outside [Node.js Cluster](https://nodejs.org/api/cluster.html) and Browser [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Worker) APIs)

The first item on my list greatly depends on the code outside the `setTimeout` call in the current execution context. Depending on the event loop implementation, it can also depend even on other events that might have managed to interject between the current Event Queue item by virtue of arriving into the queue prior to the timer being set or even (in some implementations) by arriving before the timer has elapsed.

As JavaScript is single threaded nothing is interrupted in it's execution, and the items awaiting in the queue, including elapsed timers, are only processed when all the previous items have completely executed.

MDN, as always, gives you more detailed insight into theoretical aspects as well as the SpiderMonkey implementation of these concepts:

<https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop>
inside the setTimeout use the removeClass function to remove the 'first-start' class that you added.

```
setTimeout(function() {
$('#first').removeClass('first-pause');

```

}, 1000);