Всем привет! было много таких комментариев и хочется сразу на все здесь ответить.
1) Комментарии написаны по факту, мемоизация не бесплатна.
2) Правильная изоляция стейта лучше, чем мемоизация, этого в ролике я и не отрицал. Но в реальных кейсах хорошо изолировать стейт не всегда бывает возможным, тк он может прорастать достаточно глубоко + компоненты имеют свойство усложняться и увеличиваться в размере и со временем эта изоляция тоже ломается.
И тут возникает вопрос, что проще: запомнить 5 пропсов компонента и делать поверхностное сравнение, которое "ПОЧТИ" бесплатное, или пересчитывать состояние VDom (виртуальное дерево) для компонентов, пропсы и стейт которых никак не изменился? Думаю ответ очевиден.
3) Бывают случаи, когда мемоизация АБСОЛЮТНО бесполезна, конечно использовать тут memo нет никакого смысла. Например:
- Дочерний компонент зависит от состояния родителя, в таком случае перерисовка будет 100% и никакое мемо не спасет.
- в качестве пропсов используется children, который представляет из себя ReactNode, здесь мемоизация просто не поможет, потому что при перерисовке родителя, children, который передается пропсом будет являться новой ReactNode и перерисовка здесь будет в любом случае.
- есть и другие кейсы, когда при перерисовке родителя у нас дочерние компоненты будут перерисовываться всегда, и конечно, мемоизация тут тоже бессильна.
Вывод - правильная декомпозиция и структура компонентов важнее, но и мемоизацией пренебрегать не стоит.
НО! Теперь обсудим другую сторону медали, конечно о которой комментаторы не подумали. У вас в команде работает допустим 10-20 человек. Вы вне контекста задачи на ревью (видя всего кусочек кода, оторванный от остальной части проекта) сможете понять, что человек использовал memo, useCallback, useMemo в нужных местах и правильно декомпозировал компоненты и изолировал стейт?
Ну если вы в голове держите миллионы строк кода, то возможно и сможете. В остальных случаях я думаю нет. А вот проконтролировать, что человек правильно мемоизировал объекты, функции и массивы - можно, проконтролировать мемоизацию компонентов - тоже можно.
Привожу пример, человек в PR добавил 1 функцию (условно 10 строк кода), которую куда-то передал пропсом, функцию в useCallback не обернул. Ревьюеры посмотрели код, увидели, что функция хорошая и пропустили код дальше. Затем оказалось, что эта функция порождает 100500 перерисовок компонента, в который она передавалась.
И вот тут мы возвращаемся к вопросу, что же будет хуже, перерисовка большого куска дерева на каждый чих и нагрузка на вычислительные ресурсы системы, или же запомнить пропсы и сделать поверхностное сравнение?)
В общем вывод такой, думать в любом случае надо, если вы хотите писать код хорошо.
P.S. я тоже учусь писать хорошо и не всегда это получается, все мы учимся. Всем добра!
1) Комментарии написаны по факту, мемоизация не бесплатна.
2) Правильная изоляция стейта лучше, чем мемоизация, этого в ролике я и не отрицал. Но в реальных кейсах хорошо изолировать стейт не всегда бывает возможным, тк он может прорастать достаточно глубоко + компоненты имеют свойство усложняться и увеличиваться в размере и со временем эта изоляция тоже ломается.
И тут возникает вопрос, что проще: запомнить 5 пропсов компонента и делать поверхностное сравнение, которое "ПОЧТИ" бесплатное, или пересчитывать состояние VDom (виртуальное дерево) для компонентов, пропсы и стейт которых никак не изменился? Думаю ответ очевиден.
3) Бывают случаи, когда мемоизация АБСОЛЮТНО бесполезна, конечно использовать тут memo нет никакого смысла. Например:
- Дочерний компонент зависит от состояния родителя, в таком случае перерисовка будет 100% и никакое мемо не спасет.
- в качестве пропсов используется children, который представляет из себя ReactNode, здесь мемоизация просто не поможет, потому что при перерисовке родителя, children, который передается пропсом будет являться новой ReactNode и перерисовка здесь будет в любом случае.
- есть и другие кейсы, когда при перерисовке родителя у нас дочерние компоненты будут перерисовываться всегда, и конечно, мемоизация тут тоже бессильна.
Вывод - правильная декомпозиция и структура компонентов важнее, но и мемоизацией пренебрегать не стоит.
НО! Теперь обсудим другую сторону медали, конечно о которой комментаторы не подумали. У вас в команде работает допустим 10-20 человек. Вы вне контекста задачи на ревью (видя всего кусочек кода, оторванный от остальной части проекта) сможете понять, что человек использовал memo, useCallback, useMemo в нужных местах и правильно декомпозировал компоненты и изолировал стейт?
Ну если вы в голове держите миллионы строк кода, то возможно и сможете. В остальных случаях я думаю нет. А вот проконтролировать, что человек правильно мемоизировал объекты, функции и массивы - можно, проконтролировать мемоизацию компонентов - тоже можно.
Привожу пример, человек в PR добавил 1 функцию (условно 10 строк кода), которую куда-то передал пропсом, функцию в useCallback не обернул. Ревьюеры посмотрели код, увидели, что функция хорошая и пропустили код дальше. Затем оказалось, что эта функция порождает 100500 перерисовок компонента, в который она передавалась.
И вот тут мы возвращаемся к вопросу, что же будет хуже, перерисовка большого куска дерева на каждый чих и нагрузка на вычислительные ресурсы системы, или же запомнить пропсы и сделать поверхностное сравнение?)
В общем вывод такой, думать в любом случае надо, если вы хотите писать код хорошо.
P.S. я тоже учусь писать хорошо и не всегда это получается, все мы учимся. Всем добра!