You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DevExtreme React DataGrid处理6000+记录与160+列时的滚动骨架屏问题及性能优化咨询

DevExtreme React DataGrid处理6000+记录与160+列时的滚动骨架屏问题及性能优化咨询

我在React项目中使用DevExtreme DataGrid实现了一个数据表,这个表包含6000+条记录以及160多列。目前的运行逻辑如下:

  • 初始状态下仅加载列名称
  • 点击按钮后从API获取全部记录
  • 表格采用虚拟滚动来优化性能

不过我遇到了一个视觉问题:滚动过程中,视口的上方和下方都会出现骨架加载器,这造成了很怪异的视觉效果。下面是我简化后的实现代码:

import React, { memo } from "react";
import DataGrid, {
  Column,
  ColumnChooser,
  Export,
  Paging,
  Scrolling,
  SearchPanel,
  Selection,
  Sorting,
  Summary,
  TotalItem
} from "devextreme-react/data-grid";
import PropTypes from "prop-types"; // Import PropTypes

const DataGridComponent = memo((props) => {

  const {
    data,
    keyExpr,
    onSelectionChanged,
    selectedRows,
    columns,
    stickyIndex,
    summaryItems,
    extraColumn,
    onIconClick,
    cellRender,
    height
  } = props;

  // Memoize data to avoid re-renders on each row selection change
  const memoizedData = React.useMemo(() => data, [data]);

  // Memoize columns (if an extra column is provided)
  const memoizedColumns = React.useMemo(() => {
    return extraColumn ? [extraColumn, ...columns] : columns;
  }, [extraColumn, columns]);

  const memoizedCellRender = React.useCallback((e, col) => {
    if (cellRender) {
      return cellRender(e, col);
    }
  }, [cellRender]);

  // Detect if the screen is mobile
  const isMobile = React.useMemo(() => window.innerWidth <= 768, []);

  return (
    <div style={{ height: "100%", display: "flex", flexDirection: "column", padding: "10px 0" }}>
      <DataGrid
        dataSource={memoizedData}
        animation={{ enabled: false }}
        keyExpr={keyExpr}
        showBorders={true}
        allowColumnResizing={false}
        columnAutoWidth={true}
        height={height}
        onSelectionChanged={(e) => onSelectionChanged(e?.selectedRowKeys)}
        selectedRowKeys={selectedRows}
        showColumnLines={true}
        loadPanel={{
          enabled: false,
          showIndicator: true,
        }}
      >
        <ColumnChooser enabled />
        <Selection mode="multiple" showCheckBoxesMode="always" />
        <Scrolling mode="virtual" />
        <Paging enabled={false} />
        <Sorting mode="multiple" />
        <SearchPanel visible highlightCaseSensitive />
        <Export enabled />

        {Array.isArray(memoizedColumns) && memoizedColumns.map((col, index) => (
          <Column
            key={index}
            fixed={!isMobile && index < stickyIndex} // Disable fixed columns on mobile
            fixedPosition="left"
            dataField={col.accessorKey}
            caption={col.header}
            visible={col.is_visible}
            alignment={col.textAlign}
            allowFiltering={true}
            allowSorting={true}
            cellRender={(e) => memoizedCellRender(e, col)}
          />
        ))}

        <Summary>
          {summaryItems.map((item, index) => (
            <TotalItem
              key={index}
              column={item.column}
              summaryType={item.summaryType}
              displayFormat={item.displayFormat}
              skipEmptyValues={false}
            />
          ))}
        </Summary>
      </DataGrid>
    </div>
  );
});

// Define PropTypes
DataGridComponent.propTypes = {
  data: PropTypes.array,
  keyExpr: PropTypes.string,
  onSelectionChanged: PropTypes.func,
  selectedRows: PropTypes.array,
  columns: PropTypes.array,
  stickyIndex: PropTypes.number,
  summaryItems: PropTypes.array,
  loading: PropTypes.bool,
  onIconClick: PropTypes.func,
  cellRender: PropTypes.func,
};

// Set default props to avoid crashes
DataGridComponent.defaultProps = {
  data: [],
  keyExpr: "diamond_id",
  onSelectionChanged: () => { },
  selectedRows: [],
  columns: [],
  stickyIndex: 0,
  summaryItems: [],
  loading: true,
  onIconClick: () => { },
  cellRender: null
};

export default DataGridComponent;

关键信息

  • 使用了虚拟滚动模式
  • 滚动时骨架加载器在视口上下位置异常显示
  • 由于数据集和列数规模较大,该问题表现得尤为明显

已尝试的优化方案

  • 关闭DataGrid动画:animation: { enabled: false }
  • 通过React.useMemo优化数据和列的渲染逻辑
  • 配置虚拟滚动:<Scrolling mode="virtual" />

期望结果

希望实现流畅的滚动体验,不会出现骨架加载器或渲染异常,即便是面对大规模数据集和多列的场景,也能给用户提供无缝的操作感受。

实际结果

尽管做了上述优化,滚动过程中视口上下仍然会出现骨架加载器,视觉体验较差。

我的问题

  • 有没有办法阻止滚动时视口上下出现骨架加载器?
  • 针对DevExtreme DataGrid处理大数据集和多列的场景,还有哪些额外的优化手段?

任何能提升滚动表现和整体性能的建议或最佳实践我都非常感激!

备注:内容来源于stack exchange,提问作者Rohit Khokhar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 17:33:00