Skip to content

Commit a61ecdf

Browse files
authored
chore: Add more memo to optimize scroll render perf (#429)
* scroll erf * memo everything * update deps * comment
1 parent 39fbfd8 commit a61ecdf

File tree

3 files changed

+84
-39
lines changed

3 files changed

+84
-39
lines changed

examples/scrollX.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import Table from '../src';
33
import '../assets/index.less';
44

55
const columns = [
6-
{ title: 'title1', dataIndex: 'a', key: 'a', width: 100 },
6+
{
7+
title: 'title1',
8+
dataIndex: 'a',
9+
key: 'a',
10+
width: 100,
11+
},
712
{ title: 'title2', dataIndex: 'b', key: 'b', width: 100 },
813
{ title: 'title3', dataIndex: 'c', key: 'c', width: 100 },
914
{ title: 'title4', dataIndex: 'b', key: 'd', width: 100 },
@@ -27,7 +32,7 @@ const data = [
2732
const Demo = () => (
2833
<div>
2934
<h2>Scroll X</h2>
30-
<Table style={{ width: 800 }} scroll={{ x: true }} columns={columns} data={data} />
35+
<Table style={{ width: 800 }} scroll={{ x: 2000 }} columns={columns} data={data} />
3136
</div>
3237
);
3338

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
"prop-types": "^15.5.8",
5858
"raf": "^3.4.1",
5959
"rc-resize-observer": "^0.1.2",
60-
"rc-util": "^4.19.0",
60+
"rc-util": "^4.20.1",
6161
"react-lifecycles-compat": "^3.0.2",
6262
"shallowequal": "^1.1.0"
6363
},

src/Table.tsx

Lines changed: 76 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ const EMPTY_SCROLL_TARGET = {};
7474

7575
export const INTERNAL_HOOKS = 'rc-table-internal-hook';
7676

77+
interface MemoTableContentProps {
78+
children: React.ReactNode;
79+
pingLeft: boolean;
80+
pingRight: boolean;
81+
}
82+
const MemoTableContent = React.memo<MemoTableContentProps>(
83+
({ children }) => children as React.ReactElement,
84+
// No additional render when pinged status change.
85+
// This is not a bug.
86+
(prev, next) => prev.pingLeft !== next.pingLeft || prev.pingRight !== next.pingRight,
87+
);
88+
7789
export interface TableProps<RecordType = unknown> extends LegacyExpandableProps<RecordType> {
7890
prefixCls?: string;
7991
className?: string;
@@ -326,10 +338,13 @@ function Table<RecordType extends DefaultRecordType>(props: TableProps<RecordTyp
326338
internalHooks === INTERNAL_HOOKS ? transformColumns : null,
327339
);
328340

329-
const columnContext = {
330-
columns,
331-
flattenColumns,
332-
};
341+
const columnContext = React.useMemo(
342+
() => ({
343+
columns,
344+
flattenColumns,
345+
}),
346+
[columns, flattenColumns],
347+
);
333348

334349
// ====================== Scroll ======================
335350
const fullTableRef = React.useRef<HTMLDivElement>();
@@ -371,13 +386,13 @@ function Table<RecordType extends DefaultRecordType>(props: TableProps<RecordTyp
371386
};
372387
}
373388

374-
function onColumnResize(columnKey: React.Key, width: number) {
389+
const onColumnResize = React.useCallback((columnKey: React.Key, width: number) => {
375390
updateColsWidths(widths => {
376391
const newWidths = new Map(widths);
377392
newWidths.set(columnKey, width);
378393
return newWidths;
379394
});
380-
}
395+
}, []);
381396

382397
const [setScrollTarget, getScrollTarget] = useTimeoutLock(null);
383398

@@ -612,44 +627,69 @@ function Table<RecordType extends DefaultRecordType>(props: TableProps<RecordTyp
612627
ref={fullTableRef}
613628
{...ariaProps}
614629
>
615-
{title && <Panel className={`${prefixCls}-title`}>{title(mergedData)}</Panel>}
616-
<div className={`${prefixCls}-container`}>{groupTableNode}</div>
617-
{footer && <Panel className={`${prefixCls}-footer`}>{footer(mergedData)}</Panel>}
630+
<MemoTableContent pingLeft={pingedLeft} pingRight={pingedRight}>
631+
{title && <Panel className={`${prefixCls}-title`}>{title(mergedData)}</Panel>}
632+
<div className={`${prefixCls}-container`}>{groupTableNode}</div>
633+
{footer && <Panel className={`${prefixCls}-footer`}>{footer(mergedData)}</Panel>}
634+
</MemoTableContent>
618635
</div>
619636
);
620637

621638
if (fixColumn) {
622639
fullTable = <ResizeObserver onResize={onFullTableResize}>{fullTable}</ResizeObserver>;
623640
}
624641

642+
const TableContextValue = React.useMemo(
643+
() => ({
644+
prefixCls,
645+
getComponent,
646+
scrollbarSize,
647+
direction,
648+
}),
649+
[prefixCls, getComponent, scrollbarSize, direction],
650+
);
651+
652+
const BodyContextValue = React.useMemo(
653+
() => ({
654+
...columnContext,
655+
tableLayout: mergedTableLayout,
656+
rowClassName,
657+
expandedRowClassName,
658+
componentWidth,
659+
fixHeader,
660+
fixColumn,
661+
expandIcon: mergedExpandIcon,
662+
expandableType,
663+
expandRowByClick,
664+
expandedRowRender,
665+
onTriggerExpand,
666+
expandIconColumnIndex,
667+
indentSize,
668+
}),
669+
[
670+
columnContext,
671+
mergedTableLayout,
672+
rowClassName,
673+
expandedRowClassName,
674+
componentWidth,
675+
fixHeader,
676+
fixColumn,
677+
mergedExpandIcon,
678+
expandableType,
679+
expandRowByClick,
680+
expandedRowRender,
681+
onTriggerExpand,
682+
expandIconColumnIndex,
683+
indentSize,
684+
],
685+
);
686+
687+
const ResizeContextValue = React.useMemo(() => ({ onColumnResize }), [onColumnResize]);
688+
625689
return (
626-
<TableContext.Provider
627-
value={{
628-
prefixCls,
629-
getComponent,
630-
scrollbarSize,
631-
direction,
632-
}}
633-
>
634-
<BodyContext.Provider
635-
value={{
636-
...columnContext,
637-
tableLayout: mergedTableLayout,
638-
rowClassName,
639-
expandedRowClassName,
640-
componentWidth,
641-
fixHeader,
642-
fixColumn,
643-
expandIcon: mergedExpandIcon,
644-
expandableType,
645-
expandRowByClick,
646-
expandedRowRender,
647-
onTriggerExpand,
648-
expandIconColumnIndex,
649-
indentSize,
650-
}}
651-
>
652-
<ResizeContext.Provider value={{ onColumnResize }}>{fullTable}</ResizeContext.Provider>
690+
<TableContext.Provider value={TableContextValue}>
691+
<BodyContext.Provider value={BodyContextValue}>
692+
<ResizeContext.Provider value={ResizeContextValue}>{fullTable}</ResizeContext.Provider>
653693
</BodyContext.Provider>
654694
</TableContext.Provider>
655695
);

0 commit comments

Comments
 (0)