← Назад к вопросам

Изменится ли блокировка потока при использовании requestAnimationFrame

1.2 Junior🔥 151 комментариев
#JavaScript Core#Браузер и сетевые технологии

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

requestAnimationFrame и блокировка потока

Суть вопроса

Вопрос касается того, может ли requestAnimationFrame (rAF) предотвратить блокировку главного потока JavaScript при выполнении тяжёлых операций.

Короткий ответ

НЕТ, requestAnimationFrame не решает проблему блокировки потока. Это частая ошибка новичков.

Почему это так

requestAnimationFrame - это просто планировщик, который вызывает твой код перед следующей перерисовкой браузера (обычно на 60 fps = каждые ~16ms). Но внутри самого колбэка:

// ЭТО НЕ ПОМОГАЕТ - poток всё ещё блокируется
requestAnimationFrame(() => {
  for (let i = 0; i < 1000000000; i++) {
    // тяжёлая работа
    Math.sqrt(i);
  }
});

// Браузер не сможет обновлять страницу, пока циклвыполняется
// Результат: "зависший" UI, "рваная" анимация

Корректное использование

requestAnimationFrame полезен когда:

1. Работаешь с анимациями

let position = 0;

function animate() {
  position += 5;
  element.style.transform = `translateX(${position}px)`;
  
  if (position < 500) {
    requestAnimationFrame(animate); // вызви ещё раз
  }
}

requestAnimationFrame(animate);

Это не блокирует поток, потому что работа минимальна (просто изменение стиля).

2. Разбиение тяжёлой работы на части

Если НУЖНО сделать тяжёлую работу, разбей её:

const items = Array.from({length: 10000}, (_, i) => i);
let index = 0;
const batchSize = 100; // обработать по 100 элементов

function processBatch() {
  const end = Math.min(index + batchSize, items.length);
  
  for (let i = index; i < end; i++) {
    // обработка элемента
    processItem(items[i]);
  }
  
  index = end;
  
  if (index < items.length) {
    // Дай браузеру время на перерисовку
    requestAnimationFrame(processBatch);
  }
}

requestAnimationFrame(processBatch);

РЕАЛЬНОЕ решение блокировки потока

1. Web Workers (для действительно тяжёлых операций)

// main.js
const worker = new Worker('worker.js');

// Отправить данные в отдельный поток
worker.postMessage({data: largeDataset});

// Получить результат (не блокирует основной поток)
worker.onmessage = (e) => {
  console.log('Результат:', e.data);
  updateUI(e.data);
};
// worker.js
self.onmessage = (e) => {
  // Тяжёлые вычисления выполняются здесь
  const result = heavyComputation(e.data);
  self.postMessage(result);
};

2. setTimeout с 0 (если нужно дать возможность браузеру обновиться)

function heavyWork() {
  // часть 1
  processPart1();
  
  // Дай браузеру возможность перерисоваться
  setTimeout(() => {
    processPart2(); // часть 2
  }, 0);
}

3. Асинхронные операции (fetch, promises)

// Не блокирует основной поток
async function loadData() {
  const response = await fetch('/api/data');
  const data = await response.json();
  updateUI(data); // браузер может обновляться во время ждания
}

Таблица сравнения

МетодБлокирует потокИспользование
Обычный кодДАКогда быстро
requestAnimationFrameДА (если работа тяжёлая)Анимации, перерисовка
Web WorkersНЕТТяжёлые вычисления
setTimeoutЧастичноРазбиение работы на части
Promises/asyncНЕТ (при ожидании)Асинхронные операции

Вывод

requestAnimationFrame - это инструмент для планирования, а не для разблокировки потока. Если тебе нужно сделать тяжёлую работу без блокировки - используй Web Workers или разбей работу на части.

Изменится ли блокировка потока при использовании requestAnimationFrame | PrepBro