90% розробників React оптимізують процес перерендерингу неправильно
Більшість розробників React оптимізують процес перерендерингу неправильно. Де насправді знаходиться продуктивність React та які зміни допомагають, а також чек-лист для їх застосування.
Джерела: 90% of React Developers Optimize Re-Renders Incorrectly — Here’s What Actually Works
Наступні примітки описують практичний підхід до теми «90% розробників React оптимізують процес перерендерингу неправильно — ось що насправді ефективно». Увага зосереджується на контрактах, перевірках та замінних фрагментах коду, а не на мотиваційних аспектах. Під час етапу огляду спочатку запишіть контракт: необхідні вхідні дані, сигнал про успіх та наслідки часткової невдачі. Цей перелік допоможе зберегти чесність пізніших змін у коді. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Призначте назви елементам, визначте критерії успіху та не допускайте беззвучного часткового виконання завдань.
Справжня проблема: ми не розуміємо, коли React перерендерує
Наш підхід працює найкраще, коли його розглядають як вимірювану поверхню. Запишіть один ідеальний приклад роботи, один випадок збою та примітки щодо скасування змін перед розширенням обсягу роботи. Записуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Візуалізація витрат заздалегідь запобігає несподіваним рахункам, коли процес переходить від демо-середовища до спільних. Зберігайте витрати на обробку даних на низькому рівні та відкладайте дорогі операції обчислень на момент застосування мемоізації лише після їх вимірювання. Надмірна мемоізація може приховати баги, пов’язані з застарілими даними.
День, коли ви нарешті відкрили React Profiler
Підхід «The Day you Finally stage» найкраще функціонує, якщо його розглядати як вимірювану поверхню. Запишіть один ідеальний приклад роботи, один випадок невдачі та примітку про скасування змін перед розширенням обсягу роботи. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код. Зробіть процес генерації відображень дешевим та використовуйте складні методи обчислень лише після вимірювань, за допомогою мемоїзації. Надмірна мемоїзація може приховати помилки у застарілих параметрах.
Основна істина: Перегенерації — не ворог, а непотрібні перегенерації — так
Етап «The Core Truth Re-Renders» працює найкраще, коли його розглядають як вимірювану поверхню. Зафіксуйте один ідеальний приклад роботи, один випадок збою та примітку щодо скасування змін перед розширенням обсягу завдань. Документуйте як успішний, так і відновлювальний сценарії роботи. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації. Зберігайте витрати на обробку на низькому рівні та відкладайте дорогі операції на пізніший етап лише після вимірювань. Надмірне використання мемоайзації може приховати баги, пов’язані з застарілими даними. Етап «The Core Truth Re-Renders» працює найкраще, коли його розглядають як вимірювану поверхню. Зафіксуйте один ідеальний приклад роботи, один випадок збою та примітку щодо скасування змін перед розширенням обсягу завдань. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового виконання завдань.
Розділ 1: Ментальна модель, яка нарешті допомогла React працювати ефективно
Для розділу 1 «Етап ментального моделювання» необхідно визначити вхідні дані, виконавця кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись визначити прихований стан. Записуйте час виконання та витрати на токени або запити поруч із функціональними результатами. Чітке відображення витрат заздалегідь запобігає несподіваним рахункам під час переходу з демо-середовища у спільні середовища. У разі, коли наступним кроком є код або виклик інструменту, краще використовувати структуровані результати з перевіркою схеми, ніж вільний текст.
React = двигун виконання функцій
На етапі двигуна виконання функцій React необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Конфігурацію слід тримати окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функціоналу мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код. Стан слід розміщувати разом із компонентом, який керує змінами. Розміщення всього в глобальному сховищі ускладнює виявлення проблем з таймінгом.
Component(props) → JSX
Розділ 2: Чому ваші компоненти перерендеруються частіше, ніж ви думаєте
У розділі 2 «Чому саме ваш етап» необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Необхідно документувати як шлях успішного виконання, так і шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації. Стан слід розміщувати разом із компонентом, який керує змінами. Перенесення всього до глобального сховища ускладнює виявлення проблем із таймінгом. У розділі 2 «Чому саме ваш етап» необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте безповідомного часткового завершення роботи.
1. Вбудовані об’єкти та функції
Під час роботи над етапом «1. Вбудовані об’єкти та функції» спочатку запишіть умови використання: необхідні вхідні дані, сигнал про успішне виконання та наслідки часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Запишіть час виконання та витрати на токени або запити поруч із результатами роботи функцій. Чітке бачення витрат заздалегідь запобігає несподіваним рахункам під час переходу від демо-середовища до спільних. Розглядайте ефекти як синхронізацію з зовнішнім світом, а не як заміну значень, отриманих під час відображення.
<MyComponent options={{ theme: "dark" }} />
{} !== {}
onClick={() => doSomething()}
2. Стан піднесений занадто високо
Під час роботи над етапом 2 State Lifted Too спочатку запишіть контракт: необхідні вхідні дані, сигнал про успіх та те, що відбувається при частковій невдачі. Цей перелік допомагає зберігати чесність подальших змін у коді. Зберігайте конфігурацію окремо від коду додатку. Файли середовища, сховища секретних даних та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код. Розглядайте ефекти як синхронізацію з зовнішнім світом, а не як заміну похідних значень під час відображення.
3. Похідний стан, збережений як стан
Під час роботи над етапом „3 Derived State Stored“ спочатку запишіть умови взаємодії: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність пізніших змін у коді. Документуйте як шлях успішної роботи, так і шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої доробки. Розглядайте наслідки як синхронізацію з зовнішнім світом, а не як заміну похідних значень під час обробки даних. Під час роботи над етапом „3 Derived State Stored“ спочатку запишіть умови взаємодії: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність пізніших змін у коді. Розглядайте цей етап як умови взаємодії між вхідними даними та перевіреними результатами. Дайте назви елементам, визначте критерії успіху та не допускайте безповідомного часткового завершення роботи.
const [filtered, setFiltered] = useState([]);
useEffect(() => {
setFiltered(items.filter(...));
}, [items]);
Розділ 3: Правило, яке все змінило для мене
Етап „Розділ 3. Правила“ функціонує найкраще, якщо його розглядати як вимірювану поверхню. Запишіть один ідеальний приклад роботи, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Записуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Візуалізація витрат на ранньому етапі запобігає несподіваним рахункам, коли процес переходить від демо-середовища до спільних. Зберігайте витрати на обробку на низькому рівні та відкладайте дорогі операції обчислень на пізніший час лише після їх вимірювання. Надмірне використання мемоайзації може приховати помилки у застарілих даних.
Розділ 4: 4 рівні контролю переробки елементів у React
Розділ 4. Чотириетапний підхід найкраще функціонує, якщо його розглядати як вимірювану поверхню. Збережіть один ідеальний приклад роботи, один випадок збою та запис про скасування змін перед розширенням обсягу роботи. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код. Зробіть процес генерації змісту дешевим та використовуйте складні алгоритми лише після вимірювань, за допомогою мемоїзації. Надмірна мемоїзація може приховати помилки, пов’язані з застарілими параметрами.
Рівень 1: Структурна оптимізація (найважливіше)
Етап структурної оптимізації рівня 1 працює найкраще, коли його розглядають як вимірювану поверхню. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Документуйте як успішний, так і відновлювальний сценарії роботи. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої доробки. Зберігайте витрати на обробку на низькому рівні та відкладайте дорогі процеси обчислень на пізніший етап лише після вимірювань. Надмірне використання мемоїзації може приховати баги, пов’язані з застарілими даними. Етап структурної оптимізації рівня 1 працює найкраще, коли його розглядають як вимірювану поверхню. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового завершення роботи.
Рівень 2: Мемоїзація (за потреби)
На етапі мемоїзації рівня 2 необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись визначити прихований стан. Записуйте час виконання та витрати на токени або запити поруч із функціональними результатами. Візуалізація витрат заздалегідь запобігає несподіваним рахункам, коли процес переходить від демо-середовища до спільних. Розміщуйте стан разом із компонентом, який керує змінами. Перенесення всього до глобального сховища ускладнює виявлення проблем із часом виконання.
Рівень 3: Стабільність посилань
На етапі стабільності референцій 3-го рівня необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не здогадуючись про прихований стан. Конфігурацію слід тримати окремо від коду додатку. Файли середовища, сховища секретних даних та флаги функцій мають знаходитися в одному місці, яке оператори можуть перевіряти, не читаючи весь код. Стан слід розміщувати разом із компонентом, який керує змінами. Розміщення всього в глобальному сховищі ускладнює виявлення проблем з таймінгом.
const handler = () => doSomething();
const handler = useCallback(() => {
doSomething();
}, []);
const config = useMemo(() => ({
theme: "dark"
}), []);
Рівень 4: Архітектурна ізоляція
На етапі архітектурної ізоляції рівня 4 необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Необхідно документувати як шлях успішного виконання, так і шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації. Стан слід розміщувати разом із компонентом, який керує змінами. Перенесення всього до глобального сховища ускладнює виявлення проблем з таймінгом. На етапі архітектурної ізоляції рівня 4 необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте елементи продукту, визначте критерії успіху та не допускайте безповідомного часткового завершення роботи.
Розділ 5: React.memo — найчастіше неправильно використовувана оптимізація
Під час роботи над етапом React memo у Розділі 5 спочатку запишіть контракт: необхідні вхідні дані, сигнал про успіх та те, що відбувається при частковій невдачі. Цей перелік допомагає зберігати чесність пізніших змін у коді. Записуйте час виконання та витрати на токени або запити поруч із результатами функцій. Візуалізація витрат заздалегідь запобігає несподіваним рахункам, коли код переходить з демо-середовища у спільні середовища. Розглядайте ефекти як синхронізацію з зовнішнім світом, а не як заміну значень, отриманих під час відображення.
Коли React.memo НІЧОГО не робить
Під час роботи над етапом «Коли React.memo діє», спочатку запишіть умови використання: необхідні параметри, сигнал про успіх та те, що відбувається у разі часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функціональності мають знаходитися в одному місці, щоб оператори могли їх перевіряти, не читаючи весь код. Розглядайте ефекти як синхронізацію з зовнішнім світом, а не як заміну значень, отриманих під час відображення.
Коли React.memo є корисним
Під час роботи над етапом «Коли React memo Shines», спочатку запишіть умови використання: необхідні параметри, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність у подальших змінах коду. Одночасно задокументуйте шлях успішного виконання та шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої доробки. Розглядайте ефекти як синхронізацію з зовнішнім світом, а не як заміну значень, отриманих під час відображення. Під час роботи над етапом «Коли React memo Shines», спочатку запишіть умови використання: необхідні параметри, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність у подальших змінах коду. Розглядайте цей етап як умови взаємодії між вхідними даними та перевіреними результатами. Дайте назви елементам коду, визначте критерії успіху та не допускайте безповідомного часткового завершення роботи.
Розділ 6: Пастка useCallback
Розділ 6. Етап useCallback працює найкраще, якщо його розглядати як вимірювану поверхню. Запишіть один ідеальний приклад роботи, один випадок збою та примітки щодо скасування змін перед розширенням обсягу. Записуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Візуалізація витрат на ранньому етапі запобігає несподіваним рахункам, коли процес переходить від демо-середовища до спільних. Зберігайте низькі витрати на відображення контенту та відкладайте дорогі операції обчислень після метрикування, лише за допомогою мемоізації. Надмірна мемоізація може приховати помилки у старих параметрах.
const handleClick = useCallback(() => {
setCount(c => c + 1);
}, []);
Розділ 7: Приховані витрати контексту
Rозділ 7 «Прихована стадія» працює найкраще, коли його розглядають як вимірювану поверхню. Запишіть один ідеальний приклад роботи, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь граф. Зробіть процес відображення дешевим та виконуйте складні обчислення лише після вимірювань, за допомогою мемоїзації. Надмірна мемоїзація може приховати помилки старих значень параметрів.
Погано:
Етап «Погано» найкраще функціонує, якщо його розглядати як вимірювану поверхню. Запишіть один ідеальний варіант виконання, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Документуйте як успішний, так і відновлювальний сценарії роботи разом. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації. Зберігайте витрати на обробку низькими та відкладайте дорогі операції обчислень на пізніший етап лише після їх вимірювання. Надмірне використання мемоайзування може приховати баги, пов’язані з застарілими даними.
<AuthContext.Provider value={{ user, theme }}>
Kраще:
Етап «Краще» функціонує найкраще, якщо його розглядати як вимірювану поверхню. Збережіть один ідеальний приклад виконання, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Віддавайте перевагу невеликим, тестованим одиницям перед об’ємними скриптами. Коли якийсь крок зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану послідовність дій. Зробіть процес генерації результатів дешевим та використовуйте складні методи обчислень лише після вимірювань, за допомогою мемоїзації. Надмірна мемоїзація може приховати баги, пов’язані з застарілими даними.
<UserContext />
<ThemeContext />
Розділ 8: Списки, ключі та ілюзія стабільності
Етап Section 8 Lists Keys працює найкраще, якщо його розглядати як вимірювану поверхню. Запишіть один ідеальний результат, один випадок невдачі та примітку про скасування змін перед розширенням обсягу роботи. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не погоджуйтесь на мовчазне часткове виконання завдань. Зберігайте витрати на обробку даних на низькому рівні та відкладайте дорогі операції обчислень на пізніший час лише після їх вимірювання. Надмірне використання мемоайзування може приховати баги, пов’язані з застарілими даними.
items.map((item, i) => <Row key={i} />)
items.map(item => <Row key={item.id} />)
Розділ 9: персональний чек-лист ефективності
Розділ 9 «Персональна стадія» працює найкраще, коли його розглядають як вимірювану поверхню. Запишіть один ідеальний результат, один випадок невдачі та примітку про скасування змін перед розширенням обсягу роботи. Записуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Візуалізація витрат заздалегідь запобігає несподіваним рахункам, коли процес переходить від демо-середовища до спільних. Зберігайте витрати на обробку на низькому рівні та відкладайте дорогі операції обчислень на момент застосування мемоізації лише після їх вимірювання. Надмірна мемоізація може приховати баги, пов’язані з застарілими даними.
Розділ 10: Велика зміна мислення
Розділ 10 «The Big stage» найкраще функціонує, якщо його розглядати як вимірювану поверхню. Збережіть один ідеальний приклад роботи, один випадок збою та запис про скасування змін перед розширенням обсягу роботи. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код. Зробіть процес генерації зображень дешевим та використовуйте складні методи обчислень лише після вимірювань за допомогою мемоайзації. Надмірна мемоайзація може приховати помилки у застарілих параметрах.
Останні думки: справжня таємниця
Остаточні міркування. Етап Real працює найкраще, коли його розглядають як вимірювану поверхню. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Документуйте як шлях успішної роботи, так і шлях відновлення одночасно. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої доробки. Зберігайте витрати на обробку низькими та відкладайте дорогі операції на пізніший етап лише після вимірювань. Надмірне використання мемоайзації може приховати баги, пов’язані з застарілими даними. Остаточні міркування. Етап Real працює найкраще, коли його розглядають як вимірювану поверхню. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового завершення роботи.
Продуктивність та оптимізація React
На етапі оптимізації продуктивності React необхідно визначити вхідні дані, відповідальну особу за кожен крок та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан.