For the sake of performances, we can now safely use 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, 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- 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
/* Seconds to (STRING)HH:MM:SS.MS ------------------------*/_x000D_
/* This time format is compatible with FFMPEG ------------*/_x000D_
function secToTimer(sec){_x000D_
const o = new Date(0), p = new Date(sec * 1000)_x000D_
return new Date(p.getTime()-o.getTime()).toString().split(" ")[4] + "." + p.getMilliseconds()_x000D_
}_x000D_
_x000D_
/* Countdown loop ----------------------------------------*/_x000D_
let job, origin = new Date().getTime()_x000D_
const timer = () => {_x000D_
job = requestAnimationFrame(timer)_x000D_
OUT.textContent = secToTimer((new Date().getTime() - origin) / 1000)_x000D_
}_x000D_
_x000D_
/* Start looping -----------------------------------------*/_x000D_
requestAnimationFrame(timer)_x000D_
_x000D_
/* Stop looping ------------------------------------------*/_x000D_
// cancelAnimationFrame(job)_x000D_
_x000D_
/* Reset the start date ----------------------------------*/_x000D_
// origin = new Date().getTime()
_x000D_
span {font-size:4rem}
_x000D_
<span id="OUT"></span>_x000D_
<br>_x000D_
<button onclick="origin = new Date().getTime()">RESET</button>_x000D_
<button onclick="requestAnimationFrame(timer)">RESTART</button>_x000D_
<button onclick="cancelAnimationFrame(job)">STOP</button>
_x000D_