From 2a04c30f414994ef739f316eafbbcb3b1e5bc0bb Mon Sep 17 00:00:00 2001 From: tmcintyre Date: Tue, 16 Jan 2018 13:02:16 +0000 Subject: [PATCH 1/9] table performance improvements - reducing rerendering where possible --- packages/table-dev-app/src/mutableTable.tsx | 16 +++-- packages/table/src/cell/cell.tsx | 17 +++--- packages/table/src/common/batcher.ts | 4 +- packages/table/src/table.tsx | 68 +++++++++++++++------ 4 files changed, 68 insertions(+), 37 deletions(-) diff --git a/packages/table-dev-app/src/mutableTable.tsx b/packages/table-dev-app/src/mutableTable.tsx index 5fd322d060..3b8cb60bbf 100644 --- a/packages/table-dev-app/src/mutableTable.tsx +++ b/packages/table-dev-app/src/mutableTable.tsx @@ -45,15 +45,15 @@ import { LocalStore } from "./localStore"; import { SlowLayoutStack } from "./slowLayoutStack"; export enum FocusStyle { - TAB = "tab", - TAB_OR_CLICK = "tab-or-click", + TAB, + TAB_OR_CLICK, } export enum CellContent { - EMPTY = "empty", - CELL_NAMES = "cell-names", - LONG_TEXT = "long-text", - LARGE_JSON = "large-json", + EMPTY, + CELL_NAMES, + LONG_TEXT, + LARGE_JSON, } type IMutableStateUpdateCallback = ( @@ -211,6 +211,7 @@ export interface IMutableTableState { scrollToRegionType?: RegionCardinality; scrollToRowIndex?: number; selectedFocusStyle?: FocusStyle; + selectedRegions: IRegion[]; showCallbackLogs?: boolean; showCellsLoading?: boolean; showColumnHeadersLoading?: boolean; @@ -256,6 +257,7 @@ const DEFAULT_STATE: IMutableTableState = { scrollToRegionType: RegionCardinality.CELLS, scrollToRowIndex: 0, selectedFocusStyle: FocusStyle.TAB, + selectedRegions: [], showCallbackLogs: true, showCellsLoading: false, showColumnHeadersLoading: false, @@ -375,6 +377,7 @@ export class MutableTable extends React.Component<{}, IMutableTableState> { renderMode={this.state.renderMode} rowHeaderCellRenderer={this.renderRowHeader} selectionModes={this.getEnabledSelectionModes()} + selectedRegions={this.state.selectedRegions} styledRegionGroups={this.getStyledRegionGroups()} > {this.renderColumns()} @@ -905,6 +908,7 @@ export class MutableTable extends React.Component<{}, IMutableTableState> { private onSelection = (selectedRegions: IRegion[]) => { this.maybeLogCallback(`[onSelection] selectedRegions =`, ...selectedRegions); + this.setState({selectedRegions}); }; private onColumnsReordered = (oldIndex: number, newIndex: number, length: number) => { diff --git a/packages/table/src/cell/cell.tsx b/packages/table/src/cell/cell.tsx index 25dfb11479..710c766016 100644 --- a/packages/table/src/cell/cell.tsx +++ b/packages/table/src/cell/cell.tsx @@ -7,7 +7,7 @@ import * as classNames from "classnames"; import * as React from "react"; import * as Classes from "../common/classes"; -import { Classes as CoreClasses, IIntentProps, IProps, Utils as CoreUtils } from "@blueprintjs/core"; +import { Classes as CoreClasses, IIntentProps, IProps } from "@blueprintjs/core"; import { LoadableContent } from "../common/loadableContent"; import { JSONFormat } from "./formats/jsonFormat"; @@ -93,20 +93,19 @@ export type ICellRenderer = (rowIndex: number, columnIndex: number) => React.Rea export const emptyCellRenderer = () => ; +/* + * Not a PureComponent because any children don't get included in the shallow comparison. + * - if we have children we always want to rerender in case the children have changed. + * - if we don't have children the rerender is so cheap it isn't a problem. + * + * Note that due to React's typings we can't check for the presence of children in shouldComponentUpdate() in a typesafe way. + */ export class Cell extends React.Component { public static defaultProps = { truncated: true, wrapText: false, }; - public shouldComponentUpdate(nextProps: ICellProps) { - // deeply compare "style," because a new but identical object might have been provided. - return ( - !CoreUtils.shallowCompareKeys(this.props, nextProps, { exclude: ["style"] }) || - !CoreUtils.deepCompareKeys(this.props.style, nextProps.style) - ); - } - public render() { const { cellRef, diff --git a/packages/table/src/common/batcher.ts b/packages/table/src/common/batcher.ts index 5e170d8386..a87b41a483 100644 --- a/packages/table/src/common/batcher.ts +++ b/packages/table/src/common/batcher.ts @@ -129,14 +129,14 @@ export class Batcher { const keysToAdd = this.setKeysDifference(this.batchArgs, this.currentObjects, addNewLimit); keysToAdd.forEach(key => (this.currentObjects[key] = callback.apply(undefined, this.batchArgs[key]))); - // set `done` to true of sets match exactly after add/remove and there + // set `done` to true if sets match exactly after add/remove and there // are no "old objects" remaining this.done = this.setHasSameKeys(this.batchArgs, this.currentObjects) && Object.keys(this.oldObjects).length === 0; } /** - * Returns true of the "current" set matches the "batch" set. + * Returns true if the "current" set matches the "batch" set. */ public isDone() { return this.done; diff --git a/packages/table/src/table.tsx b/packages/table/src/table.tsx index 3c9d7a4863..ae531b3583 100644 --- a/packages/table/src/table.tsx +++ b/packages/table/src/table.tsx @@ -681,28 +681,36 @@ export class Table extends AbstractComponent { selectionModes, } = nextProps; - const newChildArray = React.Children.toArray(children) as Array>; + const hasNewChildren = this.props.children !== nextProps.children; + const newChildArray = hasNewChildren ? React.Children.toArray(children) as Array> : this.childrenArray; const numCols = newChildArray.length; - // Try to maintain widths of columns by looking up the width of the - // column that had the same `ID` prop. If none is found, use the - // previous width at the same index. - const previousColumnWidths = newChildArray.map((child: React.ReactElement, index: number) => { - const mappedIndex = this.columnIdToIndex[child.props.id]; - return this.state.columnWidths[mappedIndex != null ? mappedIndex : index]; - }); - - // Make sure the width/height arrays have the correct length, but keep - // as many existing widths/heights when possible. Also, apply the - // sparse width/heights from props. + let gridInvalidationRequired = false; let newColumnWidths = this.state.columnWidths; - newColumnWidths = Utils.arrayOfLength(newColumnWidths, numCols, defaultColumnWidth); - newColumnWidths = Utils.assignSparseValues(newColumnWidths, previousColumnWidths); - newColumnWidths = Utils.assignSparseValues(newColumnWidths, columnWidths); + if (defaultColumnWidth !== this.props.defaultColumnWidth || columnWidths !== this.props.columnWidths || (hasNewChildren && !this.areChildrenSameShape(newChildArray))) { + // Try to maintain widths of columns by looking up the width of the + // column that had the same `ID` prop. If none is found, use the + // previous width at the same index. + const previousColumnWidths = newChildArray.map((child: React.ReactElement, index: number) => { + const mappedIndex = this.columnIdToIndex[child.props.id]; + return this.state.columnWidths[mappedIndex != null ? mappedIndex : index]; + }); + + // Make sure the width/height arrays have the correct length, but keep + // as many existing widths/heights when possible. Also, apply the + // sparse width/heights from props. + newColumnWidths = Utils.arrayOfLength(newColumnWidths, numCols, defaultColumnWidth); + newColumnWidths = Utils.assignSparseValues(newColumnWidths, previousColumnWidths); + newColumnWidths = Utils.assignSparseValues(newColumnWidths, columnWidths); + gridInvalidationRequired = true; + } let newRowHeights = this.state.rowHeights; - newRowHeights = Utils.arrayOfLength(newRowHeights, numRows, defaultRowHeight); - newRowHeights = Utils.assignSparseValues(newRowHeights, rowHeights); + if (defaultRowHeight !== this.props.defaultRowHeight || rowHeights !== this.props.rowHeights) { + newRowHeights = Utils.arrayOfLength(newRowHeights, numRows, defaultRowHeight); + newRowHeights = Utils.assignSparseValues(newRowHeights, rowHeights); + gridInvalidationRequired = true; + } let newSelectedRegions = selectedRegions; if (selectedRegions == null) { @@ -724,9 +732,13 @@ export class Table extends AbstractComponent { newSelectedRegions, ); - this.childrenArray = newChildArray; - this.columnIdToIndex = Table.createColumnIdIndex(this.childrenArray); - this.invalidateGrid(); + if (hasNewChildren) { + this.childrenArray = newChildArray; + this.columnIdToIndex = Table.createColumnIdIndex(this.childrenArray); + } + if (gridInvalidationRequired) { + this.invalidateGrid(); + } this.setState({ columnWidths: newColumnWidths, focusedCell: newFocusedCell, @@ -737,6 +749,22 @@ export class Table extends AbstractComponent { }); } + private areChildrenSameShape(newChildArray: Array>) { + if (this.childrenArray.length !== newChildArray.length) { + return false; + } + return this.childrenArray.every((child, index) => { + const newChild = newChildArray[index]; + if (child === newChild) { + return true; + } + if (child == null || newChild == null) { + return false; + } + return child.props.id === newChild.props.id; + }); + } + public render() { const { children, From 7d3780e90a5c54f61e65f5f70f7169a9aaa5de27 Mon Sep 17 00:00:00 2001 From: tmcintyre Date: Tue, 16 Jan 2018 13:04:39 +0000 Subject: [PATCH 2/9] reinstate enum strings --- packages/table-dev-app/src/mutableTable.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/table-dev-app/src/mutableTable.tsx b/packages/table-dev-app/src/mutableTable.tsx index 3b8cb60bbf..9ad688b574 100644 --- a/packages/table-dev-app/src/mutableTable.tsx +++ b/packages/table-dev-app/src/mutableTable.tsx @@ -45,15 +45,15 @@ import { LocalStore } from "./localStore"; import { SlowLayoutStack } from "./slowLayoutStack"; export enum FocusStyle { - TAB, - TAB_OR_CLICK, + TAB = "tab", + TAB_OR_CLICK = "tab-or-click", } export enum CellContent { - EMPTY, - CELL_NAMES, - LONG_TEXT, - LARGE_JSON, + EMPTY = "empty", + CELL_NAMES = "cell-names", + LONG_TEXT = "long-text", + LARGE_JSON = "large-json", } type IMutableStateUpdateCallback = ( From e6ba864ef09046f1746735c82a205223bdc9f95b Mon Sep 17 00:00:00 2001 From: tmcintyre Date: Tue, 16 Jan 2018 21:46:26 +0000 Subject: [PATCH 3/9] fix compile errors --- packages/table-dev-app/src/mutableTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/table-dev-app/src/mutableTable.tsx b/packages/table-dev-app/src/mutableTable.tsx index 9ad688b574..0edebb7ef0 100644 --- a/packages/table-dev-app/src/mutableTable.tsx +++ b/packages/table-dev-app/src/mutableTable.tsx @@ -211,7 +211,7 @@ export interface IMutableTableState { scrollToRegionType?: RegionCardinality; scrollToRowIndex?: number; selectedFocusStyle?: FocusStyle; - selectedRegions: IRegion[]; + selectedRegions?: IRegion[]; showCallbackLogs?: boolean; showCellsLoading?: boolean; showColumnHeadersLoading?: boolean; From ef2688e665abf3968ec5dec653b8db6b5c3d86f0 Mon Sep 17 00:00:00 2001 From: tmcintyre Date: Tue, 16 Jan 2018 21:53:13 +0000 Subject: [PATCH 4/9] fix lint errors --- packages/table-dev-app/src/mutableTable.tsx | 2 +- packages/table/src/table.tsx | 42 ++++++++++++--------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/packages/table-dev-app/src/mutableTable.tsx b/packages/table-dev-app/src/mutableTable.tsx index 0edebb7ef0..8aefebba5b 100644 --- a/packages/table-dev-app/src/mutableTable.tsx +++ b/packages/table-dev-app/src/mutableTable.tsx @@ -908,7 +908,7 @@ export class MutableTable extends React.Component<{}, IMutableTableState> { private onSelection = (selectedRegions: IRegion[]) => { this.maybeLogCallback(`[onSelection] selectedRegions =`, ...selectedRegions); - this.setState({selectedRegions}); + this.setState({ selectedRegions }); }; private onColumnsReordered = (oldIndex: number, newIndex: number, length: number) => { diff --git a/packages/table/src/table.tsx b/packages/table/src/table.tsx index ae531b3583..f502e8d6ac 100644 --- a/packages/table/src/table.tsx +++ b/packages/table/src/table.tsx @@ -682,12 +682,18 @@ export class Table extends AbstractComponent { } = nextProps; const hasNewChildren = this.props.children !== nextProps.children; - const newChildArray = hasNewChildren ? React.Children.toArray(children) as Array> : this.childrenArray; + const newChildArray = hasNewChildren + ? (React.Children.toArray(children) as Array>) + : this.childrenArray; const numCols = newChildArray.length; let gridInvalidationRequired = false; let newColumnWidths = this.state.columnWidths; - if (defaultColumnWidth !== this.props.defaultColumnWidth || columnWidths !== this.props.columnWidths || (hasNewChildren && !this.areChildrenSameShape(newChildArray))) { + if ( + defaultColumnWidth !== this.props.defaultColumnWidth || + columnWidths !== this.props.columnWidths || + (hasNewChildren && !this.areChildrenSameShape(newChildArray)) + ) { // Try to maintain widths of columns by looking up the width of the // column that had the same `ID` prop. If none is found, use the // previous width at the same index. @@ -749,22 +755,6 @@ export class Table extends AbstractComponent { }); } - private areChildrenSameShape(newChildArray: Array>) { - if (this.childrenArray.length !== newChildArray.length) { - return false; - } - return this.childrenArray.every((child, index) => { - const newChild = newChildArray[index]; - if (child === newChild) { - return true; - } - if (child == null || newChild == null) { - return false; - } - return child.props.id === newChild.props.id; - }); - } - public render() { const { children, @@ -925,6 +915,22 @@ export class Table extends AbstractComponent { } } + private areChildrenSameShape(newChildArray: Array>) { + if (this.childrenArray.length !== newChildArray.length) { + return false; + } + return this.childrenArray.every((child, index) => { + const newChild = newChildArray[index]; + if (child === newChild) { + return true; + } + if (child == null || newChild == null) { + return false; + } + return child.props.id === newChild.props.id; + }); + } + // Hotkeys // ======= From 61d93d32c1b7ff8c92426dcfedfcaf274f2c7fb0 Mon Sep 17 00:00:00 2001 From: tmcintyre Date: Tue, 16 Jan 2018 22:35:21 +0000 Subject: [PATCH 5/9] fix test --- packages/table/src/table.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/table/src/table.tsx b/packages/table/src/table.tsx index f502e8d6ac..29a3e798eb 100644 --- a/packages/table/src/table.tsx +++ b/packages/table/src/table.tsx @@ -712,7 +712,11 @@ export class Table extends AbstractComponent { } let newRowHeights = this.state.rowHeights; - if (defaultRowHeight !== this.props.defaultRowHeight || rowHeights !== this.props.rowHeights) { + if ( + defaultRowHeight !== this.props.defaultRowHeight || + rowHeights !== this.props.rowHeights || + numRows !== this.props.numRows + ) { newRowHeights = Utils.arrayOfLength(newRowHeights, numRows, defaultRowHeight); newRowHeights = Utils.assignSparseValues(newRowHeights, rowHeights); gridInvalidationRequired = true; From 23ecc46412c3db84e7e72be6f51cfd32009897a6 Mon Sep 17 00:00:00 2001 From: tmcintyre Date: Wed, 17 Jan 2018 14:08:39 +0000 Subject: [PATCH 6/9] cell: revert changes --- packages/table/src/cell/cell.tsx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/table/src/cell/cell.tsx b/packages/table/src/cell/cell.tsx index 710c766016..25dfb11479 100644 --- a/packages/table/src/cell/cell.tsx +++ b/packages/table/src/cell/cell.tsx @@ -7,7 +7,7 @@ import * as classNames from "classnames"; import * as React from "react"; import * as Classes from "../common/classes"; -import { Classes as CoreClasses, IIntentProps, IProps } from "@blueprintjs/core"; +import { Classes as CoreClasses, IIntentProps, IProps, Utils as CoreUtils } from "@blueprintjs/core"; import { LoadableContent } from "../common/loadableContent"; import { JSONFormat } from "./formats/jsonFormat"; @@ -93,19 +93,20 @@ export type ICellRenderer = (rowIndex: number, columnIndex: number) => React.Rea export const emptyCellRenderer = () => ; -/* - * Not a PureComponent because any children don't get included in the shallow comparison. - * - if we have children we always want to rerender in case the children have changed. - * - if we don't have children the rerender is so cheap it isn't a problem. - * - * Note that due to React's typings we can't check for the presence of children in shouldComponentUpdate() in a typesafe way. - */ export class Cell extends React.Component { public static defaultProps = { truncated: true, wrapText: false, }; + public shouldComponentUpdate(nextProps: ICellProps) { + // deeply compare "style," because a new but identical object might have been provided. + return ( + !CoreUtils.shallowCompareKeys(this.props, nextProps, { exclude: ["style"] }) || + !CoreUtils.deepCompareKeys(this.props.style, nextProps.style) + ); + } + public render() { const { cellRef, From e99ee776b9f1758827b66c51a3082dff72aa9a00 Mon Sep 17 00:00:00 2001 From: tmcintyre Date: Fri, 9 Feb 2018 23:01:04 +0000 Subject: [PATCH 7/9] code review suggestions; add forceRerenderOnSelectionChange flag --- packages/table/src/table.tsx | 47 +++++++++++++++++------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/packages/table/src/table.tsx b/packages/table/src/table.tsx index 0796f49a5f..8dc360719d 100644 --- a/packages/table/src/table.tsx +++ b/packages/table/src/table.tsx @@ -167,6 +167,13 @@ export interface ITableProps extends IProps, IRowHeights, IColumnWidths { */ focusedCell?: IFocusedCellCoordinates; + /** + * If `false`, prevents rerendering of all visible cells when the selection + * state changes. Rerendering will still occur if any other relevant props change. + * @default true + */ + forceRerenderOnSelectionChange?: boolean; + /** * If defined, this callback will be invoked for each cell when the user * attempts to copy a selection via `mod+c`. The returned data will be copied @@ -410,6 +417,7 @@ export class Table extends AbstractComponent { enableGhostCells: false, enableMultipleSelection: true, enableRowHeader: true, + forceRerenderOnSelectionChange: true, loadingOptions: [], minColumnWidth: 50, minRowHeight: 20, @@ -681,24 +689,25 @@ export class Table extends AbstractComponent { defaultRowHeight, enableFocusedCell, focusedCell, + forceRerenderOnSelectionChange, numRows, rowHeights, selectedRegions, selectionModes, } = nextProps; - const hasNewChildren = this.props.children !== nextProps.children; - const newChildArray = hasNewChildren + const didChildrenChange = this.props.children !== nextProps.children; + const newChildArray = didChildrenChange ? (React.Children.toArray(children) as Array>) : this.childrenArray; const numCols = newChildArray.length; - let gridInvalidationRequired = false; + let shouldInvalidateGrid = false; let newColumnWidths = this.state.columnWidths; if ( defaultColumnWidth !== this.props.defaultColumnWidth || columnWidths !== this.props.columnWidths || - (hasNewChildren && !this.areChildrenSameShape(newChildArray)) + didChildrenChange ) { // Try to maintain widths of columns by looking up the width of the // column that had the same `ID` prop. If none is found, use the @@ -709,12 +718,13 @@ export class Table extends AbstractComponent { }); // Make sure the width/height arrays have the correct length, but keep - // as many existing widths/heights when possible. Also, apply the + // as many existing widths/heights as possible. Also, apply the // sparse width/heights from props. newColumnWidths = Utils.arrayOfLength(newColumnWidths, numCols, defaultColumnWidth); newColumnWidths = Utils.assignSparseValues(newColumnWidths, previousColumnWidths); newColumnWidths = Utils.assignSparseValues(newColumnWidths, columnWidths); - gridInvalidationRequired = true; + + shouldInvalidateGrid = true; } let newRowHeights = this.state.rowHeights; @@ -725,10 +735,13 @@ export class Table extends AbstractComponent { ) { newRowHeights = Utils.arrayOfLength(newRowHeights, numRows, defaultRowHeight); newRowHeights = Utils.assignSparseValues(newRowHeights, rowHeights); - gridInvalidationRequired = true; + shouldInvalidateGrid = true; } let newSelectedRegions = selectedRegions; + if (forceRerenderOnSelectionChange && newSelectedRegions !== this.props.selectedRegions) { + shouldInvalidateGrid = true; + } if (selectedRegions == null) { // if we're in uncontrolled mode, filter out all selected regions that don't // fit in the current new table dimensions @@ -748,11 +761,11 @@ export class Table extends AbstractComponent { newSelectedRegions, ); - if (hasNewChildren) { + if (didChildrenChange) { this.childrenArray = newChildArray; this.columnIdToIndex = Table.createColumnIdIndex(this.childrenArray); } - if (gridInvalidationRequired) { + if (shouldInvalidateGrid) { this.invalidateGrid(); } this.setState({ @@ -925,22 +938,6 @@ export class Table extends AbstractComponent { } } - private areChildrenSameShape(newChildArray: Array>) { - if (this.childrenArray.length !== newChildArray.length) { - return false; - } - return this.childrenArray.every((child, index) => { - const newChild = newChildArray[index]; - if (child === newChild) { - return true; - } - if (child == null || newChild == null) { - return false; - } - return child.props.id === newChild.props.id; - }); - } - // Hotkeys // ======= From 1e1bae2878240288ca038682811a96c15d5d9775 Mon Sep 17 00:00:00 2001 From: tmcintyre Date: Mon, 29 Oct 2018 12:44:18 +0000 Subject: [PATCH 8/9] lint --- packages/table-dev-app/src/mutableTable.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/table-dev-app/src/mutableTable.tsx b/packages/table-dev-app/src/mutableTable.tsx index 36e9237d33..df0408d18a 100644 --- a/packages/table-dev-app/src/mutableTable.tsx +++ b/packages/table-dev-app/src/mutableTable.tsx @@ -236,8 +236,8 @@ export interface IMutableTableState { scrollToRegionType?: RegionCardinality; scrollToRowIndex?: number; selectedFocusStyle?: FocusStyle; - selectedRegions?: IRegion[]; selectedRegionTransformPreset?: SelectedRegionTransformPreset; + selectedRegions?: IRegion[]; showCallbackLogs?: boolean; showCellsLoading?: boolean; showColumnHeadersLoading?: boolean; @@ -283,8 +283,8 @@ const DEFAULT_STATE: IMutableTableState = { scrollToRegionType: RegionCardinality.CELLS, scrollToRowIndex: 0, selectedFocusStyle: FocusStyle.TAB, - selectedRegions: [], selectedRegionTransformPreset: SelectedRegionTransformPreset.CELL, + selectedRegions: [], showCallbackLogs: true, showCellsLoading: false, showColumnHeadersLoading: false, From 8d852597a4fe7b0294926b28a4b775715fa66b99 Mon Sep 17 00:00:00 2001 From: Gilad Gray Date: Thu, 1 Nov 2018 15:40:28 -0700 Subject: [PATCH 9/9] default to false --- packages/table/src/table.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/table/src/table.tsx b/packages/table/src/table.tsx index ec0ddb4409..bb1ff9f32e 100644 --- a/packages/table/src/table.tsx +++ b/packages/table/src/table.tsx @@ -176,9 +176,9 @@ export interface ITableProps extends IProps, IRowHeights, IColumnWidths { focusedCell?: IFocusedCellCoordinates; /** - * If `false`, prevents rerendering of all visible cells when the selection - * state changes. Rerendering will still occur if any other relevant props change. - * @default true + * If `true`, selection state changes will cause the component to re-render. + * If `false`, selection state is ignored when deciding to re-render. + * @default false */ forceRerenderOnSelectionChange?: boolean; @@ -427,7 +427,7 @@ export class Table extends AbstractComponent { enableGhostCells: false, enableMultipleSelection: true, enableRowHeader: true, - forceRerenderOnSelectionChange: true, + forceRerenderOnSelectionChange: false, loadingOptions: [], minColumnWidth: 50, minRowHeight: 20,