Pull to refresh

Comments 11

Почти никогда не стоит. Если в реакте меняется стейт, значит, что-то должно быть перерисовано. Оборачивать вообще все дорого как с точки зрения производительности, так и с точки зрения багов

Оборачивать кое-что иногда имеет смысл

Именно! Оборачивать только, когда на то есть веская причина. Даже если кажется, что "операция дорогая, надо обернуть", если видимых проблем с перформансом нет, то не имеет смысла почти 100%

Рад, что в комментарии пришли единомышленники)

Ну насколько я понисаю в 19 реакте с новым коипилятором всё к этому и идёт. Будут после компиляции стараться оборачивать всё.

Видел проекты на 30+ мб рукописного реактовского кода, где обернуто абсолютно все и видел такие же проекты, где ничего не обернуто. Это все конечно ЦРМки были, но все же разницы не чувствуется

const Display = React.memo(function Display({ data }) {
  console.log('Рендер Display');
  return <div>{data.value}</div>;
});

function App() {
  const [count, setCount] = React.useState(0);
  const data = React.useMemo(() => ({ value: 'Статичный текст' }), []);

  return (
    <div>
      <Display data={data} />
      <button onClick={() => setCount(count + 1)}>Увеличить</button>
    </div>
  );
}

А здесь useMemo чтобы что? Чтобы на каждый рендер была проверка пустого массива зависимостей? Почему не в реф?

В этой статье я рассматривал хуки useMemo, useCallback и HOC React.memo. Чтобы показать решение проблемы с изменяющейся ссылкой у объектов, массивов и функций, для примера был использован useMemo. Но согласен, что можно было бы сделать это и через реф, возможно, об использовании рефа для оптимизации я напишу в следующей статье)

Хорошая статья, но не хватает реальных кейсов и измерений. Добавьте примеры с анализом производительности, чтобы лучше показать, когда мемоизация действительно полезна

Ответ

На первый взгляд, оборачивание increment в useCallback и Button в React.memo должно предотвратить ненужные перерисовки Button. Но в данном случае выигрыш в производительности будет либо незначительным, либо его не будет вообще.

Ответ не совсем верный. Если кейс именно как в статье - ускорения не будет вообще. Так как ваш инкремент мемоизируется следующим образом:

const increment = React.useCallback(() => setCount(count + 1), [count]);

С зависимостью - count. А значит коллбек будет пересоздаваться после каждого клика на кнопку. Значит и кнопка будет рендериться заново после каждого клика, потому как ссылка на коллбек новая.

Что бы этого не было, нужно создавать коллбек без зависимости (как вы делали ранее):

const increment = React.useCallback(() => setCount((c) => c + 1), []);

И мне кажется нужно было специально обратить внимание на эту фишку создания коллбека без зависимости.

Именно данная зависимость на count и ломает полностью оптимизацию в вопросе. А если сделать коллбек без зависимости - тогда уже можно рассуждать о том, будет ли перформанс буст и имеет ли смысл, но так он хотя бы возможен.

Отдельно про рассуждения про сложность, целесообразность, ..., скорость оптимизации из вашего вопроса:

Для тех кто это все умеет - эта информация не ценна, а для тех кто новичек - они тут ничего не запомнят и не поймут, будет просто как вода. Потому что у вас просто общие рассуждения, по верхам.

Нужно делать как в вашем же утверждении в пунктах: все мерять и сравнивать (скорость, память, сложность, размер, ...). Без замеров перформанс статьи неполны.

По вашему вопросу:

Вот есть у нас простой компонет Button, мы решили что раз он у нас простой то мы не будем мемоизировать кэллбеки для него. Компонент часто используется в сотнях мест. А вот чуть попозже нам к нему необходимо добавить состояние disabled, вроде бы небольшая доработка и компонент все еще достаточно прост. Но еще чуть позже мы добавляем лоадер, далее добавились выводы иконок еще чуть позже тултипы и т.д.

И вот наш простой компонент уже не такой уж и простой. Но его путь к "непростому" был растянут во времени и скорее всего еще и разными людьми. И вот когда то надо будет идти по всем местам где используется этот комопнент и делать оптимизации, что довольно сложно понять в моменте.

И раз, как вы и сказали, выигрыш в произоводительности будет незначительным или не будет вообще, значит и вреда особого не будет? Дак не стоит ли нам просто все оборачивать в useCallback?

По поводу усложнения читаемости кода: тут все наоборот единообразие его повышает имхо.

Sign up to leave a comment.

Articles