Симптом: долго изменяет размера куба
Решение: Использовать Chrome profiler
App.js: <Pixel />
:
CSS
only solutionrequestAnimationFrame
orsetTimeout
- Обратить внимание на CSS анимации
Симптом: лагает при изменении размера куба
Решение:
App.js
→ input[range]
→ onChange
: обернуть в debounce
Симптом: UI фризится при изменении размера куба
Решение:
React profiler → <App />
hook 2 changed → App.jsx
→ input[type=range]
→ onChange
→ startTransition(() => { setSize(size) })
Симптом: Нажать Checkbox у title: ререндерится всё приложение
Решение:
"Highlight updates" в React profiler → React profiler → <App />
hook 5 and 13 changed → App.js
→ где используется setBoldTitle
→ в отдельный компонент <Title />
(чтобы не обновлялось все приложение)
Симптом: При нажатии Show/Hide loaders ререндерится Dark theme.
Решение:
StyleProvider.js
: обернуть контекст в useMemoThemeSwitcher.js
обернуть компонент в memo
Симптом: Нажимать "Close loaders" при уже закрытых лоадерах: всё приложение ререндерится
Решение:
В редьюсере: loaderSlice.js
- Проверять
isVisible
перед изменением:if (state.isVisible) {state.isVisible = false}
- Использовать
produce
изimmer
:return produce(state, draft => {draft.isVisible = false});
Симптом: При нажатии "Show/close loader" ререндерится App.js
- <Select />
Решение:
-
state => state.logItems
, а фильтровать в<Select />
- Возвращать примитив:
state => state.logItems.filter(item => item.size >= 100).map(item =>
size: ${item.size}, color: ${item.color}).join(“;”)
- В селектор добавить
isEqual
from lodash - может быть дорого - Своя функция сравнения:
(a, b) => a.length === b.length
-
Reselect
: Селектор заменить наcreateSelector(state => state.logItems, logItems => logItems.filter(item => item.size >= 100))
- Деструктурировать значения стора как можно ниже в дереве компонентов
- Лучше дробить на более мелкие компоненты
- Изменять состояние нужно внутри функций
action
,runInAction
или метода стора (если помечен какaction
)