@asdasdqwe

Разница между requestIdleCallback и setTimeout?

// Запускается после основного потока
setTimeout(() => {}, 0)

// Тоже запускается после основного потока
requestIdleCallback(function() {});
  • Вопрос задан
  • 173 просмотра
Пригласить эксперта
Ответы на вопрос 2
dollar
@dollar
Делай добро и бросай его в воду.
Для начала вам нужно понять главное: ложки «периода простоя» не существует.

setTimeout() запускает код НЕ РАНЬШЕ, чем указанный в параметре интервал времени. Если указали 5000, то должно пройти не меньше 5 секунд.

Если вы запустили таймер 5000, затем через секунду запустили таймер 2000, затем какая-то функция нагрузила браузер непрерывной работой на 10 секунд, то второй таймер будет иметь приоритет над первым, хотя и был создан позже первого.
доказательство
function sleep(ms) { //примерное время, CPU-зависимо
  let tm = performance.now();
  for (let i=0;i<1000000*ms;i++) { let x = i*i }
  console.log('sleep(' + (performance.now()-tm).toFixed() + ') - done.')
}

setTimeout(e=>console.log('first'), 5000);
sleep(1000)
setTimeout(e=>console.log('second'), 2000);
sleep(9000)


requestIdleCallback(), насколько я понимаю, вызывает код в ближайший «интервал простоя» в порядке очереди и код может быть вызван РАНЬШЕ указанного timeout (а может и позже, смотря когда будет «простой»).
пример, когда после setTimeout
function sleep(ms) { //примерное время, CPU-зависимо
  let tm = performance.now();
  for (let i=0;i<1000000*ms;i++) { let x = i*i }
  console.log('sleep(' + (performance.now()-tm).toFixed() + ') - done.')
}

setTimeout(e=>sleep(1000),100);
setTimeout(e=>sleep(1000),100);
setTimeout(e=>sleep(1000),100);
setTimeout(e=>sleep(1000),100);
setTimeout(e=>sleep(1000),100);
setTimeout(e=>sleep(1000),100);
setTimeout(e=>sleep(1000),100);
setTimeout(e=>sleep(1000),100);
setTimeout(e=>sleep(1000),100);
setTimeout(e=>sleep(1000),100);

requestIdleCallback(e=>console.log('first'),{timeout:5000});
requestIdleCallback(e=>console.log('second'),{timeout:4000});
sleep(1000);
пример со вклиниванием в очередь setTimeout
function sleep(ms) { //примерное время, CPU-зависимо
  let tm = performance.now();
  for (let i=0;i<1000000*ms;i++) { let x = i*i }
  console.log('sleep(' + (performance.now()-tm).toFixed() + ') - done.')
}

setTimeout(e=>sleep(2000),0);
setTimeout(e=>sleep(2000),1000);
setTimeout(e=>sleep(2000),2000);
setTimeout(e=>sleep(2000),3000);
setTimeout(e=>sleep(2000),4000);
setTimeout(e=>sleep(2000),5000);
setTimeout(e=>sleep(2000),6000);
setTimeout(e=>sleep(2000),7000);
setTimeout(e=>sleep(2000),8000);
setTimeout(e=>sleep(2000),9000);

requestIdleCallback(e=>console.log('first'),{timeout:5000});
requestIdleCallback(e=>console.log('second'),{timeout:1000});
sleep(1000);
пример, когда наступает «период простоя» до фактической разгрузки
function sleep(ms) { //примерное время, CPU-зависимо
  let tm = performance.now();
  for (let i=0;i<1000000*ms;i++) { let x = i*i }
  console.log('sleep(' + (performance.now()-tm).toFixed() + ') - done.')
}

var cnt = 10;
function timer() {
  sleep(1000);
  cnt--;
  if (cnt > 0) setTimeout(timer,300);
}

setTimeout(timer,300);

requestIdleCallback(e=>console.log('first'),{timeout:5000});
requestIdleCallback(e=>console.log('second'),{timeout:4000});
sleep(1000);


requestIdleCallback() рекомендуется использовать, когда время выполнения вам не критично, при этом вы не хотите тормозить анимации, нажатия на кнопки и пр. Это всякие не важные задачи.
А setTimeout() лучше использовать тогда, когда вам нужно выполнить функцию через указанный интервал времени, но как можно скорее. Например, если от этого зависит контент на странице, без которого её отзывчивость не будет иметь смысла.
Ответ написан
Комментировать
sergiks
@sergiks Куратор тега JavaScript
♬♬
существенная разница: setTimeout() универсальный-стандартный,
а «экспериментальный» requestIdleCallback() не работает в яблочных Safari.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы