Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize table rendering #1715

Merged
merged 1 commit into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';

import block from 'bem-cn-lite';
import get from 'lodash/get';
import isEqual from 'lodash/isEqual';
import type {StringParams, TableCell, TableCellsRow, TableCommonCell} from 'shared';
import {BackgroundTable} from 'ui/libs/DatalensChartkit/ChartKit/plugins/Table/renderer/components/Table/BackgroundTable';

Expand Down Expand Up @@ -271,7 +272,11 @@ export const Table = React.memo<Props>((props: Props) => {
<BackgroundTable
dimensions={widgetDimensions}
data={{header, body, footer}}
onChangeMinWidth={setCellMinWidth}
onChangeMinWidth={(colWidths) => {
if (!isEqual(cellMinSizes, colWidths)) {
setCellMinWidth(colWidths);
}
}}
/>
</React.Fragment>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function getNoDataRow(colSpan = 1): BodyRowViewData {
};
}

function getFooterRows(table: Table<TData>, leftPositions: number[]) {
function getFooterRows(table: Table<TData>, leftPositions: (number | undefined)[]) {
return table.getFooterGroups().reduce<FooterRowViewData[]>((acc, f) => {
const cells = f.headers.map<FooterCellViewData>((cell) => {
const columnDef = cell.column.columnDef;
Expand Down Expand Up @@ -180,11 +180,6 @@ export const usePreparedTableData = (props: {
const headers = table.getHeaderGroups();
const tableRows = table.getRowModel().rows;

const enableRowGrouping = React.useMemo(
() => data.head?.some((cell) => get(cell, 'group', false)),
[data.head],
);

const rowMeasures = React.useRef<Record<string, number>>({});
React.useEffect(() => {
rowMeasures.current = {};
Expand All @@ -197,6 +192,10 @@ export const usePreparedTableData = (props: {
},
getScrollElement: () => tableContainerRef.current,
measureElement: (el) => {
const rowIndex = Number(el.getAttribute('data-index')) ?? -1;
const row = tableRows[rowIndex] as Row<TData>;
const rowId = row?.id ?? -1;

const getRowHeight = () => {
const cells = Array.from(el?.getElementsByTagName('td') || []);
const simpleCell = cells.find((c) => {
Expand All @@ -206,16 +205,11 @@ export const usePreparedTableData = (props: {
return simpleCell?.getBoundingClientRect()?.height ?? 0;
};

if (!enableRowGrouping) {
return getRowHeight();
if (rowId && typeof rowMeasures.current[rowId] === 'undefined') {
rowMeasures.current[rowId] = getRowHeight();
}

const rowIndex = el.getAttribute('data-index') ?? '';
if (rowIndex && typeof rowMeasures.current[rowIndex] === 'undefined') {
rowMeasures.current[rowIndex] = getRowHeight();
}

return rowMeasures.current[rowIndex];
return rowMeasures.current[rowId];
},
overscan: 100,
});
Expand Down Expand Up @@ -245,12 +239,28 @@ export const usePreparedTableData = (props: {
return colSizeRef.current ?? [];
}, [cols, tableMinWidth]);

const leftPositionsRef = React.useRef<(number | undefined)[]>([]);
const leftPositions = React.useMemo(() => {
return (headers[headers.length - 1]?.headers ?? []).map<number>((h) => {
const headData = h.column.columnDef.meta?.head;
const cellIndex = headData?.index ?? -1;
return colSizes.reduce((sum, _s, i) => (i < cellIndex ? sum + colSizes[i] : sum), 1);
});
const newValue = (headers[headers.length - 1]?.headers ?? []).map<number | undefined>(
(h) => {
const headData = h.column.columnDef.meta?.head;
if (!headData?.pinned) {
return undefined;
}

const cellIndex = headData?.index ?? -1;
return colSizes.reduce(
(sum, _s, i) => (i < cellIndex ? sum + colSizes[i] : sum),
1,
);
},
);

if (!isEqual(newValue, leftPositionsRef.current)) {
leftPositionsRef.current = newValue;
}

return leftPositionsRef.current;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [colSizes]);

Expand Down Expand Up @@ -335,7 +345,7 @@ export const usePreparedTableData = (props: {
const prevCells = new Array(tableRows[0]?.getVisibleCells()?.length);
return virtualItems.reduce<BodyRowViewData[]>((rowsAcc, virtualRow) => {
const row = tableRows[virtualRow.index] as Row<TData>;
const rowMeasuredHeight = rowMeasures.current[virtualRow.index];
const rowMeasuredHeight = rowMeasures.current[row.id];
const visibleCells = row.getVisibleCells();
const cells = visibleCells.reduce<BodyCellViewData[]>((acc, cell, index) => {
const originalHeadData = cell.column.columnDef.meta?.head;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {ColumnDef, SortingFnOption} from '@tanstack/react-table';
import {createColumnHelper} from '@tanstack/react-table';
import type {DisplayColumnDef, GroupColumnDef} from '@tanstack/table-core/build/lib/types';
import get from 'lodash/get';
import round from 'lodash/round';
import type {TableCellsRow, TableCommonCell, TableRow, TableTitle} from 'shared';

import type {TableWidgetData} from '../../../../../../types';
Expand Down Expand Up @@ -158,7 +159,7 @@ export function getTableTitle(config: TableWidgetData['config']): TableTitle | u
}

export function getTableSizes(table: HTMLTableElement) {
const tableScale = table?.getBoundingClientRect()?.width / table?.clientWidth;
const tableScale = round(table?.getBoundingClientRect()?.width / table?.clientWidth, 2);
let rows: HTMLTableRowElement[] = [];

rows = Array.from(
Expand Down
Loading