Skip to main content

Що робить requestIdleCallback()?

Визначення

javascript
requestIdleCallback(callback, [options])

Ця функція реєструє колбек, який буде викликаний тоді, коли браузер не зайнятий відмальовуванням або обробкою подій, тобто у простої ("idle time").


Що це означає

Браузер малює кадри приблизно 60 разів на секунду (кожні ~16.6 мс). Якщо якийсь кадр зайняв лише, скажімо, 10 мс, то в браузера залишається ~6 мс вільного часу, саме туди може потрапити твій requestIdleCallback.

Таким чином, ти можеш виконувати незначні або фонові завдання, які не критичні до часу, без гальмувань інтерфейсу.


Приклад

javascript
requestIdleCallback((deadline) => { while (deadline.timeRemaining() > 0) { console.log('Виконуємо фонове завдання'); } console.log('Браузер знову зайнятий - чекаємо наступного простою'); });

Тут:

  • deadline - спеціальний об'єкт, що передається в колбек,
  • deadline.timeRemaining() показує, скільки мілісекунд "вільно" до наступного кадру,
  • ти можеш виконувати роботу поки є час, а якщо не встиг - браузер викличе колбек знову в наступному "вікні простою".

Як працює крок за кроком

  1. Ти викликаєш requestIdleCallback(fn)
  2. Браузер додає fn до черги завдань "idle callbacks"
  3. Коли Event Loop, відмальовування і мікротаски завершені, і до наступного кадру залишається час, браузер викликає твій колбек
  4. Якщо вкладка не активна або часу немає - колбек може відкладатися

Аргументи функції

javascript
requestIdleCallback(callback, { timeout: 2000 })
  • callback(deadline) - функція, яка отримає об'єкт:
    • deadline.timeRemaining() - скільки мілісекунд лишилося "до зайнятості";
    • deadline.didTimeout - true, якщо таймаут минув і колбек викликали "примусово".
  • options.timeout - максимальний час очікування (якщо немає вільного моменту - колбек все одно виконається через заданий час).

Приклад з розбиттям важкої роботи

javascript
const tasks = Array.from({ length: 10000 }, (_, i) => i); function processTasks(deadline) { while (deadline.timeRemaining() > 0 && tasks.length > 0) { const task = tasks.shift(); // виконуємо частину роботи console.log('Оброблено задачу', task); } if (tasks.length > 0) { requestIdleCallback(processTasks); } } requestIdleCallback(processTasks);

Такий підхід дає змогу обробляти тисячі елементів без лагів: UI залишається відгукливим, тому що робота виконується у паузах між кадрами.


Відмінність від setTimeout і requestAnimationFrame

КритерійsetTimeoutrequestAnimationFramerequestIdleCallback
МетаВиконати через N мсВиконати перед перемальовуванням кадруВиконати у паузі між кадрами
ПріоритетСереднійВисокий (для анімацій)Низький (фонові завдання)
Залежить від навантаженняНіТак, синхронізується з кадромТак, викликається лише якщо браузер вільний
При неактивній вкладціМоже троттлитисяПризупиняєтьсяМоже затримуватися надовго
ВикористанняТаймери, затримкиАнімації, плавні оновленняЛегкі фонові обчислення, кеш, логіка завантаження

Важливо знати

  • requestIdleCallback - є не в усіх браузерах (наприклад, немає в Safari). Краще мати фолбек:

    javascript
    const ric = window.requestIdleCallback || function (cb) { return setTimeout(() => cb({ timeRemaining: () => 0, didTimeout: true }), 1); };
  • Його не можна використовувати для критичних завдань, оскільки він може не викликатися довго (якщо вкладка навантажена).


Підсумок

ВластивістьЗначення
Що робитьВикликає колбек, коли в браузера є вільний час
Передає об'єктdeadline з timeRemaining() і didTimeout
Коли виконуєтьсяУ "вікнах простою" між кадрами
Використовується дляФонових завдань, кешування, підвантаження даних
Скасовується черезcancelIdleCallback(id)
ПовертаєЧисловий ID, як у таймерів

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.