Чому React тепер може переривати рендер?
1. Що було раніше (React ≤ 17)
- Рендер був синхронним і блокуючим.
- Коли викликався
setState()-> React рекурсивно обходив усе піддерево і обчислював нове Virtual DOM. - Поки це відбувалося, JS-потік був повністю зайнятий - браузер не міг:
- обробляти кліки чи скрол,
- виконувати анімації,
- реагувати на введення користувача.
Тобто рендер = одна довга "неперервана" операція.
2. Fiber - фундамент для переривного рендеру
З React 16 усе дерево компонентів зберігається у вигляді пов'язаних Fiber-вузлів. Кожен Fiber - це одиниця роботи (work unit), яка містить:
type FiberNode = {
type: ComponentType;
props: any;
stateNode: any;
child: FiberNode | null;
sibling: FiberNode | null;
return: FiberNode | null;
lanes: PriorityBits;
...
}React може обробляти ці вузли по одному, а не все дерево за раз. Якщо між ними браузер каже:
"Гей, у мене подія від користувача!" React зупиняє обхід і поступається керуванням потоку.
3. Concurrent Rendering (React 18)
React перетворився на планувальник. Він стежить за пріоритетами різних завдань:
| Пріоритет | Приклад | Поведінка |
|---|---|---|
| Високий | клік, введення тексту | Виконати одразу, перервавши поточний рендер |
| Середній | перехід (transition) | Виконати, коли звільниться потік |
| Низький | фільтрація списку, підвантаження даних | Можна робити "у фоні" |
Коли надходить важливіша робота, React:
- зберігає контекст поточного Fiber-дерева;
- зупиняє поточний рендер (render phase);
- обробляє термінове оновлення;
- за потреби відновлює попередній рендер з того місця, де зупинився.
4. Що це дає
| До | Після |
|---|---|
| Рендер блокує UI | Рендер можна призупинити |
| Усі оновлення рівні | Є пріоритети |
| Не можна скасувати рендер | Можна скасувати і перерахувати |
| Ефекти викликаються один раз | Ефекти гарантовано викликаються тільки після commit-фази |
| Користувач чекає | UI лишається чутливим |
5. Приклад інтуїтивно
startTransition(() => {
setHeavyList(generateBigList()); // низькопріоритетне завдання
});Якщо в цей час користувач натисне кнопку або продовжить друкувати:
- React ставить оновлення списку на паузу,
- швидко обробляє клік (
setStateтермінового типу), - потім відновлює фоновий рендер.
UI не зависає - тому що React вміє переривати й відкладати важкі оновлення.
6. Як це пов'язано з життєвим циклом
- Render phase тепер може бути переривною і повторною. Компонент може "рендеритися" кілька разів, перш ніж потрапити в commit.
- Commit phase залишається атомарною і синхронною - зміни в DOM застосовуються тільки коли React впевнений, що рендер завершено.
- Ефекти (
useEffect,useLayoutEffect) виконуються тільки після commit - тобто вже після всіх можливих скасувань і пауз.
7. Ключові технічні причини, чому React тепер може переривати рендер
- Fiber = одиниці роботи -> React може обробляти їх покроково.
- Scheduler API (cooperative scheduling) -> React знає, скільки часу минуло, і може поступатися потоком браузеру.
- Пріоритети (lanes) -> оновлення різних типів зберігаються в "доріжках" із різним пріоритетом.
- Concurrent Mode -> React не зобов'язаний одразу фіксувати зміни, він може відкладати їх.
- Suspense і Transitions -> дозволяють відкладати "важкі" рендери без блокування UI.
8. Візуально
Render phase (може бути призупинена)
|-- Fiber A
|-- Fiber B <- React може перервати тут
| ^ користувач клікнув -> обробити термінове оновлення
`-- Fiber C (доробити пізніше)
Commit phase (завжди синхронна)
`-- Застосувати зміни в DOM9. Підсумок
React може переривати рендер, тому що тепер він - кооперативний планувальник, а не лінійний виклик функцій.
Це стало можливим завдяки:
- Fiber architecture (поділ роботи на дрібні кроки),
- Concurrent Rendering (пріоритети й асинхронність),
- Scheduler API (поступка браузеру).
У підсумку:
- UI завжди чутливий,
- рендер можна призупиняти, скасовувати й відновлювати,
- життєвий цикл став безпечнішим і точнішим у commit-фазі.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.