Пытаюсь понять RequestAnimationFrame и как он работает внутри.
Браузер имеет основной поток, который представляет собой цикл событий. Цикл событий может быть заполнен различными асинхронными событиями, такими как взаимодействие с пользователем, срабатывание таймеров, завершение сетевых вызовов и события, запускающие макет и рисование, например. ввод или JS.
Таким образом, когда функция JS аннулирует макет DOM или вызывает перерисовку, основной поток браузера перерисовывает слои, которые необходимо обновить, а поток компоновщика загружает обновленные текстуры в графический процессор, где происходит окончательный композитинг, и полученное изображение отображается на экране. .
Итак, у меня сложилось впечатление, что браузеры выполняют отрисовку только тогда, когда это действительно необходимо. Если вы фиксируете события на временной шкале Chrome Dev Tools на статической странице, на которой ничего не происходит, абсолютно никакие события не фиксируются (без макета, без рисования, без запуска кадра анимации). Имеет смысл.
Но затем вы запускаете следующий код в консоли:
function onBeforeNextRepaint() {
requestAnimationFrame(onBeforeNextRepaint);
console.log('About to paint ...');
}
onBeforeNextRepaint();
Теперь вы снова захватываете события временной шкалы и замечаете события «Анимационный кадр запущен», и ваша консоль регистрируется с сообщением «О рисовании ...».
Согласно MDN,
Метод Window.requestAnimationFrame() сообщает браузеру, что вы хотите выполнить анимацию, и запрашивает у браузера вызов указанной функции для обновления анимации перед следующей перерисовкой.
Это означает, что браузер постоянно рисует и, следовательно, вызывает мою функцию для регистрации сообщения перед каждой перерисовкой. Я предполагаю, что браузеры поддерживают планировщик, который вызывает вызовы краски с частотой, соответствующей частоте обновления экрана.
Теперь мое замешательство заключается в следующем:
- Основной поток браузера постоянно перерисовывает, генерирует текстуры и загружает текстуры в графический процессор, а также выполняет вызовы отрисовки (регулируется в соответствии с частотой обновления экрана)? (Звучит неэффективно)
- Это причина, по которой мой обратный вызов onBeforeNextRepaint вызывается постоянно?
- Если 1 и 2 верны, то почему при первом захвате временной шкалы я не фиксирую события «Обновить деревья слоев» и «Композитные слои»?