Що таке Concurrent Rendering?
Визначення простими словами
Concurrent Rendering - це новий режим роботи React, при якому React може переривати, відкладати, відновлювати і об'єднувати рендери залежно від їхнього пріоритету.
Іншими словами: React тепер не зобов'язаний рендерити все одразу, він може робити це покроково, у фоні, і реагувати на важливі події швидше.
До React 18: «Блокуючий рендер»
Раніше (до React 18):
- React працював синхронно.
- Якщо почався рендер - він повинен був завершитися повністю, перш ніж користувач знову зможе взаємодіяти з UI.
- Це означало: великий компонент → "UI зависає" навіть при простому оновленні стану.
Приклад:
setCount(c => c + 1); // React одразу починає перерендер усього дереваПоки рендер не завершений - React не може обробити клік, скрол чи введення тексту. → UI "замерзає".
React 18: «Асинхронний (Concurrent) рендер»
Тепер React може:
- розбити рендер на частини (Fiber architecture),
- призупинити його, якщо з'явилася важливіша подія (наприклад, клік),
- доробити потім, коли потік вільний,
- і при цьому зберігати узгоджений стан UI (все або нічого).
Приклад для інтуїції
Уяви, що в тебе React-застосунок, де:
- Користувач друкує в рядку пошуку,
- А React паралельно фільтрує величезний список (10000 елементів).
До React 18:
- Поки список фільтрується, введення тексту "лагало".
У React 18:
- React позначає оновлення списку як "несрочне",
- Пріоритет отримує введення користувача,
- Список оновлюється у фоні, не блокуючи інтерфейс.
Як React це робить
Завдяки Fiber architecture React тепер:
- Розбиває дерево Virtual DOM на Fiber-вузли (одиниці роботи).
- Кожен вузол може оброблятися незалежно.
- React може:
- призупиняти роботу над деревом;
- зберігати контекст;
- відновлювати пізніше;
- повністю скасовувати незавершений рендер, якщо надійшли нові дані.
Це робить React схожим на планувальник задач (scheduler) всередині браузера.
Як працює Concurrent Rendering за кроками
1. Render phase (може бути перервана)
- React починає обчислювати, що потрібно оновити.
- Якщо браузер повідомляє: "користувач клікнув" або "анімація йде" - React ставить рендер на паузу.
2. Commit phase (завжди синхронна)
- Коли рендер закінчено - React фіксує результат у DOM.
- Тут викликаються ефекти (
useLayoutEffect,useEffect,componentDidMount).
Render може бути "асинхронним", але Commit завжди синхронний - React гарантує, що UI не опиниться "наполовину оновленим".
Приклад (з startTransition)
import { useState, startTransition } from 'react';
function App() {
const [text, setText] = useState('');
const [list, setList] = useState([]);
function handleChange(e) {
const value = e.target.value;
setText(value); // термінове оновлення (UI)
startTransition(() => {
// несрочне (фонове) оновлення
setList(Array(5000).fill(value));
});
}
return (
<>
<input value={text} onChange={handleChange} />
<div>{list.map((item, i) => <p key={i}>{item}</p>)}</div>
</>
);
}Що робить startTransition():
- Позначає оновлення як "низькопріоритетне".
- React спочатку обробить введення користувача (
setText), - А потім - у фоні оновить список (
setList).
Результат: інтерфейс залишається чуйним.
Які оновлення бувають у Concurrent Rendering
| Тип оновлення | Приклад | Пріоритет |
|---|---|---|
| Термінові | введення, кліки, навігація | Високий |
| Несрочні | фільтрація, підвантаження, візуальні оновлення | Низький |
Перехідні (startTransition) | пошук, маршрути, фонове завантаження | Середній |
Як це впливає на життєвий цикл
| Фаза | Що змінилося |
|---|---|
| Render phase | тепер асинхронна і може перериватися |
| Commit phase | залишається синхронною |
Ефекти (useEffect, useLayoutEffect) | можуть викликатися і очищатися кілька разів (у dev / concurrent режимі) |
| Монтування | може бути "змодельоване" кілька разів до реального commit (для перевірки чистоти ефектів) |
Реактивні API, додані для Concurrent Rendering
| API | Призначення |
|---|---|
startTransition() | Позначити оновлення як "несрочне" |
useTransition() | Повернути прапорець isPending і startTransition |
useDeferredValue() | Відкласти застосування значення (наприклад, фільтр) |
useId() | Генерація стабільних ID, безпечна для асинхронного рендера |
useSyncExternalStore() | Безпечне читання зовнішнього стану в concurrent-режимі |
useInsertionEffect() | Контрольоване вставлення стилів у concurrent-режимі |
Чому це важливо
UI не зависає при важких операціях. React може скасовувати непотрібні оновлення (економія ресурсів). Можливість "безшовних" переходів між станами. Готова база для React Suspense, Streaming SSR і Server Components.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.