perf(plugin-chart-table): Add memoization to avoid rerenders (#19976)

* perf(plugin-chart-table): Add memoization to avoid rerenders

* Fix typing
This commit is contained in:
Kamil Gabryjelski
2022-05-13 18:10:48 +02:00
committed by GitHub
parent 35e6e2709c
commit 0f68deedf1
8 changed files with 81 additions and 45 deletions

View File

@@ -36,6 +36,7 @@ import {
Row,
} from 'react-table';
import { matchSorter, rankings } from 'match-sorter';
import { typedMemo } from '@superset-ui/core';
import GlobalFilter, { GlobalFilterProps } from './components/GlobalFilter';
import SelectPageSize, {
SelectPageSizeProps,
@@ -74,7 +75,7 @@ const sortTypes = {
};
// Be sure to pass our updateMyData and the skipReset option
export default function DataTable<D extends object>({
export default typedMemo(function DataTable<D extends object>({
tableClassName,
columns,
data,
@@ -124,7 +125,7 @@ export default function DataTable<D extends object>({
const defaultGetTableSize = useCallback(() => {
if (wrapperRef.current) {
// `initialWidth` and `initialHeight` could be also parameters like `100%`
// `Number` reaturns `NaN` on them, then we fallback to computed size
// `Number` returns `NaN` on them, then we fallback to computed size
const width = Number(initialWidth) || wrapperRef.current.clientWidth;
const height =
(Number(initialHeight) || wrapperRef.current.clientHeight) -
@@ -287,7 +288,7 @@ export default function DataTable<D extends object>({
let resultCurrentPage = pageIndex;
let resultOnPageChange: (page: number) => void = gotoPage;
if (serverPagination) {
const serverPageSize = serverPaginationData.pageSize ?? initialPageSize;
const serverPageSize = serverPaginationData?.pageSize ?? initialPageSize;
resultPageCount = Math.ceil(rowCount / serverPageSize);
if (!Number.isFinite(resultPageCount)) {
resultPageCount = 0;
@@ -299,7 +300,7 @@ export default function DataTable<D extends object>({
if (foundPageSizeIndex === -1) {
resultCurrentPageSize = 0;
}
resultCurrentPage = serverPaginationData.currentPage ?? 0;
resultCurrentPage = serverPaginationData?.currentPage ?? 0;
resultOnPageChange = (pageNumber: number) =>
onServerPaginationChange(pageNumber, serverPageSize);
}
@@ -354,4 +355,4 @@ export default function DataTable<D extends object>({
) : null}
</div>
);
}
});

View File

@@ -162,6 +162,9 @@ function SelectPageSize({
);
}
const getNoResultsMessage = (filter: string) =>
t(filter ? 'No matching records found' : 'No records found');
export default function TableChart<D extends DataRecord = DataRecord>(
props: TableChartTransformedProps<D> & {
sticky?: DataTableProps<D>['sticky'];
@@ -474,12 +477,12 @@ export default function TableChart<D extends DataRecord = DataRecord>(
[columnsMeta, getColumnConfigs],
);
const handleServerPaginationChange = (
pageNumber: number,
pageSize: number,
) => {
updateExternalFormData(setDataMask, pageNumber, pageSize);
};
const handleServerPaginationChange = useCallback(
(pageNumber: number, pageSize: number) => {
updateExternalFormData(setDataMask, pageNumber, pageSize);
},
[setDataMask],
);
return (
<Styles>
@@ -497,9 +500,7 @@ export default function TableChart<D extends DataRecord = DataRecord>(
onServerPaginationChange={handleServerPaginationChange}
// 9 page items in > 340px works well even for 100+ pages
maxPageItemCount={width > 340 ? 9 : 7}
noResults={(filter: string) =>
t(filter ? 'No matching records found' : 'No records found')
}
noResults={getNoResultsMessage}
searchInput={includeSearch && SearchInput}
selectPageSize={pageSize !== null && SelectPageSize}
// not in use in Superset, but needed for unit tests

View File

@@ -31,7 +31,10 @@ import {
TimeFormats,
TimeFormatter,
} from '@superset-ui/core';
import { getColorFormatters } from '@superset-ui/chart-controls';
import {
ColorFormatters,
getColorFormatters,
} from '@superset-ui/chart-controls';
import isEqualColumns from './utils/isEqualColumns';
import DateWithFormatter from './utils/DateWithFormatter';
@@ -189,6 +192,8 @@ const getPageSize = (
return numRecords * numColumns > 5000 ? 200 : 0;
};
const defaultServerPaginationData = {};
const defaultColorFormatters = [] as ColorFormatters;
const transformProps = (
chartProps: TableChartProps,
): TableChartTransformedProps => {
@@ -198,7 +203,7 @@ const transformProps = (
rawFormData: formData,
queriesData = [],
filterState,
ownState: serverPaginationData = {},
ownState: serverPaginationData,
hooks: { onAddFilter: onChangeFilter, setDataMask = () => {} },
} = chartProps;
@@ -237,7 +242,7 @@ const transformProps = (
? totalQuery?.data[0]
: undefined;
const columnColorFormatters =
getColorFormatters(conditionalFormatting, data) ?? [];
getColorFormatters(conditionalFormatting, data) ?? defaultColorFormatters;
return {
height,
@@ -249,7 +254,9 @@ const transformProps = (
serverPagination,
metrics,
percentMetrics,
serverPaginationData,
serverPaginationData: serverPagination
? serverPaginationData
: defaultServerPaginationData,
setDataMask,
alignPositiveNegative,
colorPositiveNegative,