Проблема производительности с React 16.8.5 с большим количеством набора данных - PullRequest
0 голосов
/ 30 марта 2020

У меня есть таблица, и ее ячейки можно выбирать (используя реагировать на выбор-быстрый ). Есть 15000 строк, и каждая строка имеет 30 выбираемых ячеек. У меня странная проблема с повторным рендерингом. Повторное рендеринг компонента занимает больше времени.

Вот ссылка песочницы кода для того же самого: https://codesandbox.io/s/unruffled-vaughan-vnox7

Проблема в том, когда я удаляю setState метод, то он работает как положено, так как нет повторного рендеринга. Но так как событие в ячейке должно быть записано в родительском компоненте, чтобы внести изменения в другую форму страницы (недоступно в изолированной программной среде кода), поэтому мне нужно обновить состояние компонента, тогда страница отображение выделенных ячеек занимает больше времени, чем обычно.

Здесь можно увидеть сбой: https://vnox7.csb.app/

Что-то я здесь не так делаю?

Ответы [ 2 ]

3 голосов
/ 30 марта 2020

Реагирует, чтобы быть быстрым, но может стать очень медленным.

Почему?

Проблема № 1 - использование компонентов функций в любом месте.

Проблема с компонентом функции заключается в том, что он рендерит каждый раз при рендеринге родителя. Таким образом, если у вас есть некоторые тяжелые вычисления внутри функционального компонента (и у вас есть), вы будете бороться. Даже если DOM не будет обновлен после пересчета (из-за теневой проверки DOM), вам все равно нужно рассчитать все для сравнения.

Взгляните сюда:

const getRows = number => { 
   *heavy calculation*
}

И здесь:

 <table border="1">
        <thead>
          <tr>{getHead()}</tr>
        </thead>
        <tbody>{getRows(1500)}</tbody>
      </table>

В каждом рендере вы выполняете одни и те же вычисления, которые вам на самом деле не нужны.

Как исправить: - заменить функциональный компонент на чистый компонент. (Или используйте response.memo для функционального компонента)

Issue # 2 - выделение мусора (извините за такое сильное слово, но это правда)

onSelectionFinish={selected => {
        console.time("EEEE");
        console.log("Selection Started");
        onSelect(selected);
      }}
      ignoreList={[".name-col", ".h-col", ".s-col", ".u-col", ".v-col"]}

Здесь, на каждом рендере Вы создаете новый массив и новый обработчик. Это увеличит использование памяти и работу сборщика мусора. Обычно это не проблема, но если ваш компонент часто рендерится, это станет проблемой. Или, если вы выделяете большое количество объектов, как вы делаете в getRows (). Стоит отметить, что сбор мусора полностью остановит ваше приложение.

Как исправить: - пересчитать все, что можно, и использовать результаты вместо расчетов на лету. Это сэкономит вам много процессорного времени.

Надеюсь, это поможет!

ОБНОВЛЕНИЕ Как уже упоминалось @YashJoshi,

техника оконного управления может очень помогите здесь

Чтобы получить больше информации, пожалуйста, отметьте здесь

1 голос
/ 01 апреля 2020

@ Drag13 @ YashJoshi,

Я полностью согласен, что windowing поможет здесь, но также мы должны учитывать, что изменение ячейки не должно повторно отображать всю таблицу (текущее окно) или любой другой компонент на странице

@ SonuBamniya вместо использования родительского компонента для захвата состояния, которое вы должны рассмотреть, используя React Context / redux / любую другую библиотеку управления состоянием, которая фиксирует изменение ячейки. Кроме того, разделите каждую ячейку на отдельный компонент, который обновляет контекст, и затем вы можете использовать этот контекст в компоненте формы вместо всего родительского компонента.

Это значительно сократит количество повторных визуализаций.

...