react-virtualized — включить или отключить виртуализацию

Я использую самый дерзкий компонент react-virtualized в приложении, похожем на календарь. м работаю.

Я использую три сетки с ScrollSync, как в этот пример, но также используя cellRangeRenderer для рендеринга "таблеток" поверх сетки.

Приложение работает очень хорошо, однако я обнаружил, что на более медленных компьютерах рендеринг при прокрутке может быть довольно медленным (может быть около 40 столбцов на 20 строк и до 40 или около того таблеток, отображаемых в одном представлении).

Некоторым людям, которые будут использовать это приложение, на самом деле не нужна виртуализация, потому что общая таблица данных не настолько велика. Итак, что я хотел бы сделать, так это продолжать использовать общую структуру, которую предоставляет react-virtualized, но для пользователей со строками ‹ x, но просто визуализировать всю сетку за один раз, чтобы, надеюсь, улучшить производительность. Для пользователей со строками > x сетки будут виртуализированы как обычно.

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

Мне было бы интересно услышать любые предложения или подобный опыт.


person oldo.nicho    schedule 21.10.2017    source источник


Ответы (2)


Я бы посоветовал не использовать компоненты react-virtualized, когда количество строк достаточно мало, чтобы не требовать виртуализации. Это добавляет сложности и т. д. без необходимости. :)

Вы можете создать поддельный компонент Grid, который просто отображает все строки, а затем условно переключается между ним и реальным на основе количества строк, например:

import {Grid} from 'react-virtualized';
import FakeGrid from './FakeGrid';

// Your render function
const GridComponent = this.props.rowCount > SOME_THRESHOLD
  ? Grid
  : FakeGrid

return <GridComponent {...gridProps} />
person bvaughn    schedule 21.10.2017
comment
Спасибо @brianvaughn, я поэкспериментирую с этим. Я хотел бы использовать как можно больше преимуществ react-virtualized (в частности, функции cellRangeRenderer и scrollSync), поэтому я попробую ваше предложение и посмотрю, что из этого получится. Дам тебе знать. Как всегда, спасибо за вашу активность в этом проекте :-) - person oldo.nicho; 22.10.2017
comment
поскольку большая часть логики и функциональности, которые я разработал, заключена в react-virtualized компонентах, было бы замечательно, если бы был способ просто отобразить всю сетку один раз, но перехватить любые вызовы для повторного рендеринга. Я пытался найти источник для Grid, но не понимаю, как этого добиться. У Вас есть какие-то предложения? - person oldo.nicho; 24.10.2017
comment
Я думаю, вы могли бы подделать это, задав RV определенную ширину + высоту + количество строк / столбцов, чтобы заставить его изначально отображать определенное количество строк + столбцов, а затем в componentDidMount установить флаг состояния, который сообщает, что рендеринг теперь ведет себя нормально, вы' повторно работает в браузере. - person bvaughn; 24.10.2017
comment
Спасибо, Брайан. В итоге я просто оставил его с виртуализацией на все случаи жизни. В конце концов мне удалось взломать решение для рендеринга всей сетки с использованием предложенного вами метода, но время рендеринга было очень медленным. Ваше здоровье. - person oldo.nicho; 08.11.2017

У меня есть компонент, который оборачивает Table из react-virtualized, которому я передаю реквизит fixedHeight (boolean), и использую его следующим образом:

import {
  AutoSizer,
  Table as VirtualizedTable
} from 'react-virtualized';

const Table = (props) => {
  const getHeight = (autoSizerHeight) => {
    const { fixedHeight, headerHeight, rowHeight, rowCount } = props;

    // I'm checking for `rowCount` in order to properly render the `noRowsRenderer` component
    return fixedHeight && rowCount
      ? headerHeight + rowHeight * rowCount
      : autoSizerHeight;
  }
  
  return (
    <AutoSizer
      disableHeight={props.fixedHeight && Boolean(rowCount)}>
      {({ height, width }) => (
        <VirtualizedTable
          ...
          width={width}
          height={getHeight(height)}>
          {props.columnDefs.map(
            (columnDef, columnIndex) => (
              <Column ... />
            )
          )}
        </VirtualizedTable>
      )}
    </AutoSizer>
  );
}

Примечание.

Я не отказываюсь от виртуализации, я обычно использую реквизит fixedHeight, когда не хочу прокручивать таблицу или когда данные разбиты на страницы, а страницы невелики.

Надеюсь, поможет :)

person Daniel    schedule 09.03.2020
comment
Спасибо за решение. Я взгляну :-) - person oldo.nicho; 10.03.2020