2

Let's say I'm running a laggy app in the background of my computer.

This lag also affects the browser's performance (in this case Firefox).

And now, I build a JavaScript timer with this code:

let seconds = 10;
let countdown = setInterval(() => {
  if (seconds <= 0) return clearInterval(countdown);
  document.querySelector("#timer").textContent = seconds;
  seconds--;
}, 1000);

This timer would work fine if my performance wasn't so bad.

Delayed timer example

Look closely at the number countdown, and you can see how the delay always changes from 1 second - 3 seconds.

How can I make this countdown sync with the performance, so it always decrements 1 second instead of delaying?

ProOfficial
  • 101
  • 8
  • So you are basically asking "how can I make a performant timer if my app is super unperformant"? Because you can see the issue here, right? Perhaps a web worker could run a separate process, but the update would still be laggy. Improving overall performance is your best bet, as timers _always_ get executed after a cycle, and if that cycle takes long, there's no way to improve it. – somethinghere May 05 '23 at 14:11
  • 1
    @somethinghere I am building a game and I want it to be fair for everyone. So let's say one player has a super PC and this game runs like a knife through butter. Then, one player is using their cracked hand-me-down iPhone 2, and the timer would be delayed, making the game start earlier for the better PC player. How can I make it run each second without the performance delaying it? – ProOfficial May 05 '23 at 14:17
  • Well, you... can't. Javascript is single threaded so you thread will _always_ be blocked by code it is executing. A web worker might be able to do the countdown in a sort-of other thread, but your main thread still needs to perform the DOM update in order, after executing the rest of the cycle. There's no way to do this without improving overall performance of your app for everyone. Browsers just aren't the platform you should target if you want to do this, I think. – somethinghere May 05 '23 at 14:23

1 Answers1

1

Try using a recursive setTimeout instead, it should be more consistent than setInterval.

let seconds = 10;
let countdown = setTimeout(function countdownCallback() {
  if (seconds <= 0) return;
  document.querySelector("#timer").textContent = seconds;
  seconds--;
  setTimeout(countdownCallback,1000);
}, 1000);

If that doesn't work then there's nothing else that can be done.