Швидкість реакції React починається з організації дерева компонентів
Повторна обробка не є ворогом — великомасштабне поширення даних є. Перемістіть джерела ближче до листків перед мікрозберіганням.
React робить те, що вимагає архітектура у вигляді дерева. Коли додаток працює повільно, це часто означає, що фреймворк дотримується складного шляху поширення стану/обновлень, а не працює некоректно без видимих причин.
Повторне відрендерування — не ворог
Відрендерування — це засіб для підтримки послідовності інтерфейсу. Справжнім ворогом є непотрібна робота з великими піддеревами при кожному натисканні клавіші.
// ❌ count lives in Parent — expensive siblings re-render on every click
function Parent() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(c => c + 1)}>Count: {count}</button>
<ExpensiveComponent />
<AnotherExpensiveComponent />
</div>
);
}
// ✅ count lives in Counter — expensive siblings are untouched
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(c => c + 1)}>
Count: {count}
</button>
);
}
function Parent() {
return (
<div>
<Counter />
<ExpensiveComponent />
<AnotherExpensiveComponent />
</div>
);
}
// ❌ SearchLayout owns state — ExpensiveList re-renders on every keystroke
function SearchLayout() {
const [query, setQuery] = useState('');
return (
<div>
<input value={query} onChange={e => setQuery(e.target.value)} />
<ExpensiveList />
</div>
);
}
/* ✅ StatefulInput receives expensive content as children
— its reference stays stable */
function StatefulInput({ children }) {
const [query, setQuery] = useState('');
return (
<div>
<input value={query} onChange={e => setQuery(e.target.value)} />
{children}
</div>
);
}
function SearchLayout() {
return (
<StatefulInput>
<ExpensiveList />
</StatefulInput>
);
}
Де має зупинитися поширення
Розміщення джерела даних
Розміщуйте стан поруч із компонентами, які його записують та читають. Текст проекту форми не обов’язково має знаходитися у корені додатку.
Блокування шляху поширення
Дочірні компоненти, які приймають стабільні параметри, можуть уникати зайвої роботи. Композиція та використання дочірніх компонентів як слотів часто є кращими рішеннями, ніж загальне застосування механізму memo.
Дерево як архітектурне рішення
Організація коду — це архітектурний вибір: папки з функціями, розділення на контейнери та презентаційний шар, а також локальні провайдери впливають на радіус поширення оновлень.
Початок з дерева
Перш ніж переходити до мікрооптимізацій, сплануйте, який стан має знаходитися де та які піддерева повинні залишатися стабільними під час частих оновлень. Більшість скарг на повільність React стосуються саме структури дерева.
Спочатку проаналізуйте, потім реорганізуйте; мемоїзацію застосовуйте в кінці.
Провайдери контексту є частиною дерева: мегаконтекст, який змінюється при кожному відображенні, скасовує ефект мемоїзації листків. Розділяйте контексти за частотою оновлень.
Розділення коду на рівні маршрутів зменшує обсяг дерева, який потрібно обробляти під час першого відображення; поєднуйте його з локальним станом, щоб навігація залишалась легкою.
Віртуалізація списків — це своєрідна „хірургія дерева“: видаляйте рядки, які знаходяться поза екраном, замість того щоб опрацьовувати тисячі неактивних вузлів.
Власність на документ: яка команда володіє станом певної піддеревини. Спільні глобальні сховища створюють проблему широкого поширення змін під іншою назвою.
Використовуйте інформацію про час виконання операцій commit у React Profiler до та після зміни стану; зберігайте різницю у PR для перегляду.
Компоненти сервера та клієнтські острівці змінюють місце розташування дерева, але правила поширення змін все одно діють у клієнтському острівці.
Постачальники контексту є частиною дерева: мегаконтекст, який змінюється при кожному відображенні, скасовує ефект memo для листків дерева. Розділяйте контексти за частотою оновлень.
Розділення коду на рівні маршрутів зменшує обсяг дерева, за яке потрібно платити під час першого відображення; поєднуйте його з локальним станом, щоб навігація залишалась легкою.
Віртуалізація списків — це своєрідна „хірургія“ дерева: видаляйте з екрану рядки, які знаходяться поза полем зору, замість того щоб обробляти тисячі неактивних вузлів.
Власність на документ: яка команда володіє станом певної піддеревини. Спільні глобальні сховища створюють проблему широкого поширення змін під іншою назвою.
Використовуйте інформацію про час виконання операцій commit у React Profiler до та після зміни стану; зберігайте різницю у PR для перегляду.
Компоненти сервера та клієнтські острівці змінюють місце розташування дерева, але правила поширення змін все одно діють у клієнтському острівці.
Постачальники контексту є частиною дерева: мегаконтекст, який змінюється при кожному відображенні, скасовує ефект memo для листків дерева. Розділяйте контексти за частотою оновлень.
Розділення коду на рівні маршрутів зменшує обсяг дерева, за яке потрібно платити під час першого відображення; поєднуйте його з локальним станом, щоб навігація залишалась легкою.
Віртуалізація списків — це своєрідна „хірургія“ дерева: видаляйте рядки, які знаходяться поза екраном, замість того щоб працювати з тисячами неактивних вузлів.
Власність на документ: яка команда володіє станом певної піддеревини. Спільні глобальні сховища створюють проблему широкого поширення змін під іншою назвою.
Використовуйте інформацію про час виконання операцій commit у React Profiler до та після зміни стану; зберігайте різницю у PR для перегляду.
Компоненти сервера та клієнтські острівці змінюють місце розташування дерева, але правила поширення змін все одно діють у клієнтському острівці.
Постачальники контексту є частиною дерева: мегаконтекст, який змінюється при кожному відображенні, скасовує ефект memo для листків дерева. Розділяйте контексти за частотою оновлень.
Розділення коду на рівні маршрутів зменшує обсяг дерева, за яке потрібно платити під час першого відображення; поєднуйте його з локальним станом, щоб навігація залишалась легкою.
Віртуалізація списків — це своєрідна „хірургія“ дерева: видаляйте рядки, які знаходяться поза екраном, замість того щоб працювати з тисячами неактивних вузлів.
Власність на документ: яка команда володіє станом певної піддеревини. Спільні глобальні сховища створюють проблему широкого поширення змін під іншою назвою.
Використовуйте інформацію про час виконання операцій commit у React Profiler до та після зміни стану; зберігайте різницю у PR для перегляду.
Компоненти сервера та клієнтські острівці змінюють місце розташування дерева, але правила поширення змін все одно діють у клієнтському острівці.
Постачальники контексту є частиною дерева: мегаконтекст, який змінюється при кожному відображенні, скасовує ефект memo для листків дерева. Розділяйте контексти за частотою оновлень.
Розділення коду на рівні маршрутів зменшує обсяг дерева, за яке потрібно платити під час першого відображення; поєднуйте його з локальним станом, щоб навігація залишалась легкою.
Віртуалізація списків — це своєрідна „хірургія“ дерева: видаляйте з екрану рядки, які знаходяться поза полем зору, замість того щоб обробляти тисячі неактивних вузлів.
Власність на документ: яка команда володіє станом певної піддеревини. Спільні глобальні сховища створюють проблему широкого поширення змін під іншою назвою.
Використовуйте інформацію про час виконання операцій commit у React Profiler до та після зміни стану; зберігайте різницю у PR для перегляду.
Компоненти сервера та клієнтські острівці змінюють місце розташування дерева, але правила поширення змін все одно діють у клієнтському острівці.
Постачальники контексту є частиною дерева: мегаконтекст, який змінюється при кожному відображенні, скасовує ефект memo для листків дерева. Розділяйте контексти за частотою оновлень.
Розділення коду на рівні маршрутів зменшує обсяг дерева, за яке потрібно платити під час першого відображення; поєднуйте його з локальним станом, щоб навігація залишалась легкою.
Віртуалізація списків — це своєрідна „хірургія“ дерева: видаляйте з екрану рядки, які знаходяться поза полем зору, замість того щоб обробляти тисячі неактивних вузлів.
Власність на документ: яка команда володіє станом певної піддеревини. Спільні глобальні сховища створюють проблему широкого поширення змін під іншою назвою.
Використовуйте інформацію про час виконання операцій commit у React Profiler до та після зміни стану; зберігайте різницю у PR для перегляду.
Компоненти сервера та клієнтські острівці змінюють місце розташування дерева, але правила поширення змін все одно діють у клієнтському острівці.
Постачальники контексту є частиною дерева: мегаконтекст, який змінюється при кожному відображенні, скасовує ефект memo для листків дерева. Розділяйте контексти за частотою оновлень.
Розділення коду на рівні маршрутів зменшує обсяг дерева, за яке потрібно платити під час першого відображення; поєднуйте його з локальним станом, щоб навігація залишалась легкою.
Віртуалізація списків — це своєрідна „хірургія“ дерева: видаляйте з екрану рядки, які знаходяться поза полем зору, замість того щоб обробляти тисячі неактивних вузлів.
Власність на документ: яка команда володіє станом певної піддеревини. Спільні глобальні сховища створюють проблему широкого поширення змін під іншою назвою.
Використовуйте інформацію про час виконання операцій commit у React Profiler до та після зміни стану; зберігайте різницю у PR для перегляду.
Компоненти сервера та клієнтські острівці змінюють місце розташування дерева, але правила поширення змін все одно діють у клієнтському острівці.
Постачальники контексту є частиною дерева: мегаконтекст, який змінюється при кожному відображенні, скасовує ефект memo для листків дерева. Розділяйте контексти за частотою оновлень.
Розділення коду на рівні маршрутів зменшує обсяг дерева, за яке потрібно платити під час першого відображення; поєднуйте його з локальним станом, щоб навігація залишалась легкою.
Віртуалізація списків — це своєрідна „хірургія“ дерева: видаляйте з екрану рядки, які знаходяться поза полем зору, замість того щоб обробляти тисячі неактивних вузлів.
Власність на документ: яка команда володіє станом певної піддеревини. Спільні глобальні сховища створюють проблему широкого поширення змін під іншою назвою.
Використовуйте інформацію про час виконання операцій commit у React Profiler до та після зміни стану; зберігайте різницю у PR для перегляду.
Компоненти сервера та клієнтські острівці змінюють місце розташування дерева, але правила поширення змін все одно діють у клієнтському острівці.
Постачальники контексту є частиною дерева: мегаконтекст, який змінюється при кожному відображенні, скасовує ефект memo для листків дерева. Розділяйте контексти за частотою оновлень.
Розділення коду на рівні маршрутів зменшує обсяг дерева, за яке потрібно платити під час першого відображення; поєднуйте його з локальним станом, щоб навігація залишалась легкою.
Постачальники, які оновлюються при кожному натисканні клавіші, повинні огортати лише ті компоненти, яким потрібна така частота оновлень — а не всю структуру сторінки.
Похідні дані мають знаходитися у селекторах або у запам’ятованих дочірніх елементах, а не відображатися у стані сусідніх елементів, що призводить до більшої кількості відрендерувань.
Візуалізуйте дерево: намальовуйте клітинки для власників стану та стрілки для параметрів. Широкі гілки, що виходять від кореня, — це типова ознака.
Функції, які працюють одночасно, допомагають у ситуаціях терміновості, але вони не можуть виправити проблему з «бог-компонентом», який контролює кожне поле складного майстра.
Тактика міграції: щоразу під час внесення змін переміщуйте один елемент стану до листка дерева за допомогою профілера перед та після змін.
Провайдери, які оновлюються з кожним натисканням клавіші, повинні охоплювати лише ті компоненти-споживачі, яким потрібна така частота оновлень, а не всю структуру сторінки.
Похідні дані мають знаходитися у селекторах або у запам’ятованих дочірніх елементах, а не відображатися у стані сусідніх елементів, що призводить до більшої кількості відрендерувань.
Візуалізуйте дерево: намальовуйте клітинки для власників стану та стрілки для параметрів. Широкі гілки, що виходять від кореня, — це типова ознака.
Функції, що працюють одночасно, допомагають у ситуаціях терміновості, але вони не можуть виправити «бог-компонент», який контролює кожне поле складного магічного інструменту.
Тактика міграції: щоразу після подання PR переміщуйте один елемент стану вглиб ієрархії за допомогою профілера та додавайте його дані до файлу перед та після змін.
Проviderи, які оновлюються з кожним натисканням клавіші, повинні охоплювати лише ті компоненти-споживачі, яким потрібна така частота оновлень, а не всю структуру сторінки.
Похідні дані мають знаходитися у селекторах чи у запам’ятованих дочірніх елементах, а не відображатися у сусідніх елементах, що призводить до більшої кількості відображень.
Візуалізуйте ієрархію: намальовуйте клітинки для елементів, які контролюють стан, та стрілки для їхніх параметрів. Широке розгалуження від кореня є звичайною ознакою проблеми.
Функції, що працюють одночасно, допомагають у ситуаціях терміновості, але вони не можуть виправити «бог-компонент», який контролює кожне поле складного магічного інструменту.
Тактика міграції: щоразу після подання PR переміщуйте один елемент стану вглиб ієрархії за допомогою профілера та додавайте його дані до файлу перед та після змін.
Провайдери, які оновлюються з кожним натисканням клавіші, повинні обгортати лише ті компоненти-споживачі, яким потрібна така частота оновлень, а не всю структуру сторінки.
Похідні дані мають знаходитися у селекторах або у запам’ятованих дочірніх елементах, а не відображатися у стані сусідніх елементів, що призводить до додаткових відрендерувань.
Візуалізуйте дерево: намальовуйте клітинки для власників стану та стрілки для параметрів. Широке розгалуження від кореня є звичайною ознакою такої структури.