Настройка интервального таймера замедляется при переходе на другую вкладку Chrome

#javascript

#javascript

Вопрос:

Я создаю таймер обратного отсчета, поэтому, когда я остаюсь на вкладке Chrome с обратным отсчетом, он работает нормально. Но когда я перехожу на другую вкладку (во время обратного отсчета), это замедляет работу.

например, когда вы начинаете обратный отсчет в течение 30 секунд и переходите на другую вкладку на 10 секунд, когда вы возвращаетесь на вкладку обратного отсчета, это будет через 24 секунды — вместо 20 секунд (это просто пример, который очень изменчив).

 stopper = setTimeout(progressCountdown, 1000);
  

progressCountdown функция здесь не нужна, потому что она отлично работает, когда я на вкладке обратного отсчета.

Есть какой-нибудь способ это исправить?

Ответ №1:

Не гарантируется, что тайм-аут будет запущен точно после заданной задержки. На самом деле, может быть несколько причин, по которым задержка будет больше указанной вами, например, если ваша веб-страница или процессор перегружены работой, или если браузер регулирует ее для экономии энергии и заряда батареи (что многие браузеры делают с фоновыми вкладками). В MDN есть список со многими причинами, по которым это может произойти.

Однако, похоже, ваша реальная проблема заключается в том, что вы используете таймауты для отслеживания самого времени. Это часто будет очень неточно из-за вышеуказанных проблем. Вместо этого вам следует использовать часы для отслеживания времени, затраченного до истечения тайм-аута:

 // performance.now() is a good way of measuring durations
let atStart = performance.now();

function timeoutCallback() {
  let now = performance.now();
  
  // milliseconds is accurate now matter how long the timeout actually took
  // no matter if in foreground or in background tab
  let milliseconds = now - atStart;

  // number of seconds left
  let secondsLeft = Math.ceil(30 - milliseconds / 1000);
  console.log('Countdown: '   secondsLeft);

  if(secondsLeft > 0)
    setTimeout(timeoutCallback, 1000);
}

setTimeout(timeoutCallback, 1000);  

Комментарии:

1. ваш код великолепен, но только для отслеживания, я пытаюсь придумать способ объединить ваш код с моим обратным отсчетом, но у меня нет.

2. @AmandaWhite Я обновил свой пример, чтобы он был реальным обратным отсчетом, надеюсь, это более полезно.