Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить requestAnimationFrame()?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`requestAnimationFrame(callback)`** - це вбудований API браузера, який планує виконання функції `callback` перед наступним кадром відмальовування (перед "перемальовуванням екрана"). **Ключове:** браузер викликає колбек в оптимальний момент, приблизно 60 разів на секунду, щоб анімація виглядала максимально плавною і без ривків.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Визначення `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 / setInterval` | `requestAnimationFrame` | |---|---|---| | Частота | Фіксована (наприклад, кожні 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`) | | **Зупиняється автоматично** | Так, якщо вкладка неактивна | | **Тип задачі** | Окрема черга для візуальних оновлень (до рендера) | | **Ідеально підходить для** | Анімацій, плавних трансформацій, прогрес-барів |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.