--- sidebar_position: 8 --- # Ререндер страницы в контексте event loop Ререндер (перерисовка страницы) и event loop действительно тесно связаны в браузере, хотя происходят на разных уровнях работы движка. ## 🧠 Что такое event loop (цикл событий) Event Loop — это механизм, который координирует выполнение JavaScript и обновление пользовательского интерфейса в браузере. Он следит за очередями задач (macrotasks и microtasks) и периодически синхронизирует результаты с рендерингом страницы. Упрощённо: 1. JS выполняется в однопоточном окружении. 2. Когда движок сталкивается с асинхронной задачей (таймер, fetch, промис), она попадает в очередь. 3. Event loop циклически: - берёт задачу из очереди макротасков (например, setTimeout, fetch, click), - выполняет её, - затем обрабатывает все микротаски (например, .then, queueMicrotask), - и только после этого может произойти рендер (отрисовка кадра). ## 🎨 Где тут ререндер страницы Ререндер (или «перерисовка кадра») происходит между циклами event loop, после того как: - закончено выполнение всех JS-задач текущей итерации (включая microtasks), - браузер свободен, - и наступает момент обновления UI (обычно раз в 16,6 мс для 60 fps). Можно представить цикл так: ```text [ Выполнение JS ] → [ Очередь microtasks ] → [ Пересчёт layout / repaint / composite ] → [ Следующий event loop tick ] ``` ## 📅 Когда браузер решает перерисовать страницу Браузер не будет рендерить страницу посреди выполнения JavaScript — это важно. Рендеринг откладывается, пока: - не закончится текущая макротаска, - не будут выполнены все микротаски (Promise callbacks), - и браузер решит, что пора обновить UI. Например: ```js console.log("start"); Promise.resolve().then(() => { document.body.style.background = "red"; console.log("microtask done"); }); console.log("end"); ``` Порядок событий: ```text start end microtask done [перерисовка после microtasks — фон становится красным] ``` ## ⚙️ Пример с блокировкой рендера Если ты сделаешь что-то тяжёлое в JS, например: ```js while (true) {} // бесконечный цикл ``` — event loop не сможет дойти до стадии «рендера», и страница «замрёт». Поэтому анимации, реактивные интерфейсы и плавные переходы требуют, чтобы JS отдавал управление обратно браузеру (через requestAnimationFrame, setTimeout, await, и т.д.). ## Как requestAnimationFrame вписывается в event loop requestAnimationFrame (rAF) — это специальный API, который браузер вызывает перед следующей перерисовкой. Это позволяет выполнять обновления DOM/Canvas синхронно с циклом рендера, без пропусков кадров. ```bash → JS выполняется → rAF callback запланирован → microtasks выполняются → браузер вызывает rAF callback → обновление layout/repaint → кадр готов ``` ## 🧩 В контексте фреймворков (React, Vue и т.п.) Когда React вызывает setState(), обновления не происходят мгновенно: - Они ставятся в очередь микрозадач или макрозадач (в зависимости от режима). - После завершения текущего JS-такта React вычисляет новый виртуальный DOM. - Затем браузер, на этапе рендера event loop, перерисовывает изменённые части UI. Таким образом, **event loop управляет моментом**, когда обновления React реально становятся видимыми. ## 📊 Итоговое резюме | Этап | Что делает | |--------------|---------------------------------------------------------------------| | Macrotask | Выполняет основную JS-задачу (скрипт, обработчик события и т.д.) | | Microtasks | Обрабатывает все промисы и микрозадачи | | Render phase | После JS — браузер вычисляет layout, стили и отрисовывает изменения | | Next tick | Начинается следующий цикл event loop | ### Визуальная схема event loop и рендера (в виде диаграммы)