Question: I want to use a simple countdown timer starting at 30 seconds from when the function is run and ending at 0. No milliseconds. How can it be coded?

Answer: 
Here is another one if anyone needs one for minutes and seconds:

```
    var mins = 10;  //Set the number of minutes you need
    var secs = mins * 60;
    var currentSeconds = 0;
    var currentMinutes = 0;
    /* 
     * The following line has been commented out due to a suggestion left in the comments. The line below it has not been tested. 
     * setTimeout('Decrement()',1000);
     */
    setTimeout(Decrement,1000); 

    function Decrement() {
        currentMinutes = Math.floor(secs / 60);
        currentSeconds = secs % 60;
        if(currentSeconds <= 9) currentSeconds = "0" + currentSeconds;
        secs--;
        document.getElementById("timerText").innerHTML = currentMinutes + ":" + currentSeconds; //Set the element id you need the time put into.
        if(secs !== -1) setTimeout('Decrement()',1000);
    }

```
For the sake of performances, we can now safely use [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) for fast looping, instead of setInterval/setTimeout.

When using setInterval/setTimeout, if a loop task is taking more time than the interval, the browser will simply extend the interval loop, to continue the full rendering. This is creating issues. After minutes of **setInterval/setTimeout overload, this can freeze the tab, the browser or the whole computer.**

Internet devices have a wide range of performances, so it's quite impossible to hardcode a fixed interval time in milliseconds!

Using the [Date object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date), to compare the start Date Epoch and the current. This is way faster than everything else, the browser will take care of everything, at a steady **60FPS** (1000 / 60 = **16.66ms by frame**) -*[a quarter of an eye blink](https://sciencing.com/fast-blink-eye-5199669.html)*- and if the task in the loop is requiring more than that, the browser will drop some repaints. 

This allow a margin before our eyes are noticing (**Human = 24FPS** => 1000 / 24 = 41.66ms by frame = fluid animation!)

<https://caniuse.com/#search=requestAnimationFrame>

```js
/* Seconds to (STRING)HH:MM:SS.MS ------------------------*/
/* This time format is compatible with FFMPEG ------------*/
function secToTimer(sec){
  const o = new Date(0), p =  new Date(sec * 1000)
  return new Date(p.getTime()-o.getTime()).toString().split(" ")[4] + "." + p.getMilliseconds()
}

/* Countdown loop ----------------------------------------*/
let job, origin = new Date().getTime()
const timer = () => {
  job = requestAnimationFrame(timer)
  OUT.textContent = secToTimer((new Date().getTime() - origin) / 1000)
}

/* Start looping -----------------------------------------*/
requestAnimationFrame(timer)

/* Stop looping ------------------------------------------*/
// cancelAnimationFrame(job)

/* Reset the start date ----------------------------------*/
// origin = new Date().getTime()
```

```css
span {font-size:4rem}
```

```html
<span id="OUT"></span>
<br>
<button onclick="origin = new Date().getTime()">RESET</button>
<button onclick="requestAnimationFrame(timer)">RESTART</button>
<button onclick="cancelAnimationFrame(job)">STOP</button>
```