Skip to main content

Що таке Concurrent Rendering?

Визначення простими словами

Concurrent Rendering - це новий режим роботи React, при якому React може переривати, відкладати, відновлювати і об'єднувати рендери залежно від їхнього пріоритету.

Іншими словами: React тепер не зобов'язаний рендерити все одразу, він може робити це покроково, у фоні, і реагувати на важливі події швидше.


До React 18: «Блокуючий рендер»

Раніше (до React 18):

  • React працював синхронно.
  • Якщо почався рендер - він повинен був завершитися повністю, перш ніж користувач знову зможе взаємодіяти з UI.
  • Це означало: великий компонент → "UI зависає" навіть при простому оновленні стану.

Приклад:

javascript
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 тепер:

  1. Розбиває дерево Virtual DOM на Fiber-вузли (одиниці роботи).
  2. Кожен вузол може оброблятися незалежно.
  3. React може:
  • призупиняти роботу над деревом;
  • зберігати контекст;
  • відновлювати пізніше;
  • повністю скасовувати незавершений рендер, якщо надійшли нові дані.

Це робить React схожим на планувальник задач (scheduler) всередині браузера.


Як працює Concurrent Rendering за кроками

1. Render phase (може бути перервана)

  • React починає обчислювати, що потрібно оновити.
  • Якщо браузер повідомляє: "користувач клікнув" або "анімація йде" - React ставить рендер на паузу.

2. Commit phase (завжди синхронна)

  • Коли рендер закінчено - React фіксує результат у DOM.
  • Тут викликаються ефекти (useLayoutEffect, useEffect, componentDidMount).

Render може бути "асинхронним", але Commit завжди синхронний - React гарантує, що UI не опиниться "наполовину оновленим".


Приклад (з startTransition)

javascript
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.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.