Skip to main content

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

Визначення

requestAnimationFrame(callback) - це вбудований API браузера, який запланує виконання функції callback перед наступним кадром відмальовування (перед "перемальовуванням екрана").


Що це означає на практиці

Коли браузер збирається перемалювати екран (зазвичай ~60 разів на секунду, тобто кожні 16.6 мс), він викликає твій колбек з requestAnimationFrame в оптимальний момент, щоб анімація виглядала максимально плавною і без ривків.


Приклад

javascript
function animate(time) { console.log('Кадр в', time, 'мс'); requestAnimationFrame(animate); // запитуємо наступний кадр } requestAnimationFrame(animate);

Що відбувається:

  • animate викликається перед кожним кадром відмальовування;
  • time - це timestamp (у мілісекундах), який показує, коли саме почалося відмальовування кадру (за performance.now()).

Як це працює під капотом

  1. Ти викликаєш requestAnimationFrame(fn);
  2. Функція fn зберігається браузером;
  3. Коли браузер готовий малювати новий кадр (зазвичай через 16 мс), він перед перемальовуванням викликає всі такі функції;
  4. Після виклику колбека браузер перемальовує екран.

Якщо всередині колбека знову викликати requestAnimationFrame(), анімація йтиме в циклі - кадр за кадром.


Приклад плавного руху елемента

javascript
const box = document.querySelector('.box'); let start = null; function move(timestamp) { if (!start) start = timestamp; const progress = timestamp - start; box.style.transform = `translateX(${progress / 5}px)`; if (progress < 2000) { // 2 секунди requestAnimationFrame(move); } } requestAnimationFrame(move);

Тут елемент плавно переміщується протягом 2 секунд. А браузер сам оптимізує виклики - якщо вкладка не видна, requestAnimationFrame призупиняється, щоб не витрачати ресурси.


Відмінність від setTimeout / setInterval

КритерійsetTimeout / setIntervalrequestAnimationFrame
ЧастотаФіксована (наприклад, кожні 16 мс)Синхронізується з частотою оновлення екрана
ЕнергоспоживанняНе призупиняються у вкладкахАвтоматично зупиняється, якщо вкладка прихована
ПлавністьМоже "рватися" при навантаженніМаксимально плавне відмальовування
ВикористанняТаймери, фонові задачіАнімації, плавні оновлення UI
Передає timestampНіТак (performance.now() час кадру)

Приклад порівняння

javascript
function moveWithTimeout() { box.style.left = `${parseInt(box.style.left || 0) + 1}px`; setTimeout(moveWithTimeout, 16); } function moveWithRaf() { box.style.left = `${parseInt(box.style.left || 0) + 1}px`; requestAnimationFrame(moveWithRaf); }

setTimeout не враховує навантаження браузера, може "проскакувати" кадри. requestAnimationFrame підлаштовується під частоту дисплея і завжди максимально плавний.


Скасування виклику

Якщо потрібно скасувати запланований кадр:

javascript
const id = requestAnimationFrame(step); cancelAnimationFrame(id);

ПІДСУМОК

ВластивістьОпис
Що робитьЗапускає колбек перед наступним кадром відмальовування
Коли викликаєтьсяКоли браузер готовий намалювати новий кадр (~60 FPS)
Аргумент функціїtimestamp - час початку кадру
ПовертаєID кадру (для cancelAnimationFrame)
Зупиняється автоматичноТак, якщо вкладка неактивна
Тип задачіОкрема черга для візуальних оновлень (до рендера)
Ідеально підходить дляАнімацій, плавних трансформацій, прогрес-барів

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

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

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