← Назад к вопросам

Какое минимальное значение задержки у setTimeout?

1.7 Middle🔥 141 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Подробный анализ минимальной задержки setTimeout

Минимальная практически достижимая задержка setTimeout в веб-браузерах составляет 4 миллисекунды, однако важно понимать, что это поведение не гарантируется спецификацией и зависит от множества факторов.

Технические ограничения и стандарты

Согласно спецификации HTML5 (WHATWG и W3C), браузеры должны применять clamping (ограничение) для вложенных вызовов setTimeout:

// Пример демонстрации минимальной задержки
let start = Date.now();
let count = 0;

function testTimeout() {
  count++;
  const elapsed = Date.now() - start;
  console.log(`Вызов ${count}: прошло ${elapsed} мс`);
  
  if (count < 5) {
    setTimeout(testTimeout, 0); // Пытаемся выполнить с нулевой задержкой
  }
}

setTimeout(testTimeout, 0);

В современных браузерах вы увидите, что интервалы между вызовами будут примерно 4-5 мс, даже если установлена задержка 0.

Почему существует ограничение 4 мс?

  1. Защита от перегрузки CPU — без ограничений скрипт с setTimeout(callback, 0) мог бы создать бесконечный цикл, блокирующий основной поток.
  2. Совместимость с частотой обновления экрана — 4 мс соответствует ~250 Гц, что превышает типичную частоту обновления мониторов (60-144 Гц).
  3. Исторические причины — это значение унаследовано из ранних версий браузеров и стало де-факто стандартом.

Факторы, влияющие на реальную задержку

// Различия в поведении в разных контекстах
console.log("Проверка минимальной задержки:");

// Тест в активной вкладке
setTimeout(() => {
  console.log("Активная вкладка - обычно 4-5 мс");
}, 0);

// В фоновой вкладке минимальная задержка может увеличиваться
// до 1000 мс или более для оптимизации производительности

Ключевые факторы:

  • Состояние вкладки — активные вкладки имеют приоритет
  • Уровень заряда батареи — на мобильных устройствах при низком заряде задержки увеличиваются
  • Нагрузка на процессор — при высокой нагрузке таймеры замедляются
  • Режим экономии трафика — некоторые браузеры ограничивают фоновую активность

Сравнение с setImmediate и requestAnimationFrame

Для задач, требующих минимальной задержки, существуют альтернативы:

// requestAnimationFrame - синхронизируется с отрисовкой кадра (~16.7 мс при 60 Гц)
function animate() {
  // Оптимально для анимаций
  requestAnimationFrame(animate);
}

// MessageChannel или микротаски для асинхронного выполнения без задержки
Promise.resolve().then(() => {
  console.log("Микротаска - выполняется перед следующей отрисовкой");
});

// postMessage для межконтекстного взаимодействия

Практические рекомендации

  • Для анимаций всегда используйте requestAnimationFrame
  • Для фоновых задачsetTimeout с разумными интервалами (16-32 мс)
  • Для срочного асинхронного кода — микротаски (Promise.resolve().then())
  • Измеряйте производительность с помощью performance.now() вместо Date.now()

Особенности в Node.js

// В Node.js поведение отличается
const { setTimeout } = require('timers');

// В Node.js минимальная задержка может быть ~1 мс
// Но фактическое время зависит от загрузки event loop
setTimeout(() => {
  console.log('Node.js timeout');
}, 0);

В Node.js минимальная задержка теоретически может быть около 1 мс благодаря использованию libuv, но на практике также подвержена влиянию других задач в event loop.

Выводы

Хотя технически возможно установить setTimeout(fn, 0), реальная минимальная задержка составит примерно 4 миллисекунды в современных браузерах при оптимальных условиях. Это ограничение — разумный компромисс между производительностью, энергоэффективностью и отзывчивостью интерфейса. Для задач, критичных к времени выполнения, следует выбирать соответствующие API (requestAnimationFrame, микротаски, Web Workers) в зависимости от конкретных требований.