requestAnimationFrame и requestIdleCallback

↑ 7.4 Browser API · ← Предыдущая · → Следующая

Желательно~3 мин чтенияУровень: senior

Зачем это на собесе

Планирование работы — ключ к плавности. Спрашивают, чем rAF отличается от setTimeout и когда нужен idle.

requestAnimationFrame

Колбэк вызывается перед следующей перерисовкой (обычно 60 раз в секунду, синхронно с частотой экрана). Останавливается в фоновых вкладках.

let id = 0
function loop(time: DOMHighResTimeStamp) {
  update(time)
  id = requestAnimationFrame(loop)
}
id = requestAnimationFrame(loop)
// остановка
cancelAnimationFrame(id)

Применение: анимации на JS, синхронизация чтений и записей DOM, троттлинг обработчиков scroll/mousemove до кадра.

let queued = false
window.addEventListener('scroll', () => {
  if (queued) return
  queued = true
  requestAnimationFrame(() => { render(); queued = false })
})

requestIdleCallback

Колбэк выполняется, когда главный поток свободен. Для несрочных задач.

requestIdleCallback(deadline => {
  while (deadline.timeRemaining() > 0 && tasks.length) run(tasks.shift()!)
}, { timeout: 2000 })

Применение: аналитика, предзагрузка, индексация, разбиение больших вычислений на кусочки. Safari поддерживает не везде: нужен fallback на setTimeout.

Сравнение

APIКогда срабатываетДля чего
setTimeoutчерез N мс (минимум)отложенное действие
rAFперед кадромвизуальные обновления
requestIdleCallbackв простоевторостепенные задачи
queueMicrotaskпосле текущего кодасогласование состояния
scheduler.postTaskс приоритетомразбиение работы
scheduler.yield()уступить потокудлинные задачи, INP

Вопросы с ответами