fix: add patterns, rerender and js
This commit is contained in:
103
docs/browser/08-rerender_js.md
Normal file
103
docs/browser/08-rerender_js.md
Normal file
@@ -0,0 +1,103 @@
|
||||
---
|
||||
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 и рендера (в виде диаграммы)
|
||||
<img src="images/08-rerender-phases.png" width="600"/>
|
||||
|
||||
|
||||
|
||||
BIN
docs/browser/images/08-rerender-phases.png
Normal file
BIN
docs/browser/images/08-rerender-phases.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
Reference in New Issue
Block a user