1
0
mirror of https://github.com/mattermost/focalboard.git synced 2024-12-21 13:38:56 +02:00

making the table a virtual list to improve performance

This commit is contained in:
Benjamin Cooke 2023-03-03 15:11:33 -05:00
parent 098868387e
commit 2a14d8a41d
4 changed files with 133 additions and 10 deletions

View File

@ -48,6 +48,8 @@
"react-redux": "^7.2.0",
"react-router-dom": "^5.2.0",
"react-select": "^5.2.2",
"react-virtualized-auto-sizer": "^1.0.7",
"react-window": "^1.8.8",
"trim-newlines": "^4.0.2"
},
"devDependencies": {
@ -72,6 +74,8 @@
"@types/react-redux": "^7.1.23",
"@types/react-router-dom": "^5.3.3",
"@types/react-select": "^5.0.0",
"@types/react-virtualized-auto-sizer": "^1.0.1",
"@types/react-window": "^1.8.5",
"@types/redux-mock-store": "^1.0.3",
"@typescript-eslint/eslint-plugin": "^5.16.0",
"@typescript-eslint/parser": "^5.16.0",
@ -2795,6 +2799,24 @@
"@types/react": "*"
}
},
"node_modules/@types/react-virtualized-auto-sizer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz",
"integrity": "sha512-GH8sAnBEM5GV9LTeiz56r4ZhMOUSrP43tAQNSRVxNexDjcNKLCEtnxusAItg1owFUFE6k0NslV26gqVClVvong==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/react-window": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.5.tgz",
"integrity": "sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/redux-mock-store": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@types/redux-mock-store/-/redux-mock-store-1.0.3.tgz",
@ -14075,6 +14097,34 @@
"react-dom": ">=16.6.0"
}
},
"node_modules/react-virtualized-auto-sizer": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.7.tgz",
"integrity": "sha512-Mxi6lwOmjwIjC1X4gABXMJcKHsOo0xWl3E3ugOgufB8GJU+MqrtY35aBuvCYv/razQ1Vbp7h1gWJjGjoNN5pmA==",
"engines": {
"node": ">8.0.0"
},
"peerDependencies": {
"react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc",
"react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc"
}
},
"node_modules/react-window": {
"version": "1.8.8",
"resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.8.tgz",
"integrity": "sha512-D4IiBeRtGXziZ1n0XklnFGu7h9gU684zepqyKzgPNzrsrk7xOCxni+TCckjg2Nr/DiaEEGVVmnhYSlT2rB47dQ==",
"dependencies": {
"@babel/runtime": "^7.0.0",
"memoize-one": ">=3.1.1 <6"
},
"engines": {
"node": ">8.0.0"
},
"peerDependencies": {
"react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
@ -19590,6 +19640,24 @@
"@types/react": "*"
}
},
"@types/react-virtualized-auto-sizer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz",
"integrity": "sha512-GH8sAnBEM5GV9LTeiz56r4ZhMOUSrP43tAQNSRVxNexDjcNKLCEtnxusAItg1owFUFE6k0NslV26gqVClVvong==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/react-window": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.5.tgz",
"integrity": "sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/redux-mock-store": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@types/redux-mock-store/-/redux-mock-store-1.0.3.tgz",
@ -28118,6 +28186,21 @@
"prop-types": "^15.6.2"
}
},
"react-virtualized-auto-sizer": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.7.tgz",
"integrity": "sha512-Mxi6lwOmjwIjC1X4gABXMJcKHsOo0xWl3E3ugOgufB8GJU+MqrtY35aBuvCYv/razQ1Vbp7h1gWJjGjoNN5pmA==",
"requires": {}
},
"react-window": {
"version": "1.8.8",
"resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.8.tgz",
"integrity": "sha512-D4IiBeRtGXziZ1n0XklnFGu7h9gU684zepqyKzgPNzrsrk7xOCxni+TCckjg2Nr/DiaEEGVVmnhYSlT2rB47dQ==",
"requires": {
"@babel/runtime": "^7.0.0",
"memoize-one": ">=3.1.1 <6"
}
},
"read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",

View File

@ -65,6 +65,8 @@
"react-redux": "^7.2.0",
"react-router-dom": "^5.2.0",
"react-select": "^5.2.2",
"react-virtualized-auto-sizer": "^1.0.7",
"react-window": "^1.8.8",
"trim-newlines": "^4.0.2"
},
"jest": {
@ -113,6 +115,8 @@
"@types/react-redux": "^7.1.23",
"@types/react-router-dom": "^5.3.3",
"@types/react-select": "^5.0.0",
"@types/react-virtualized-auto-sizer": "^1.0.1",
"@types/react-window": "^1.8.5",
"@types/redux-mock-store": "^1.0.3",
"@typescript-eslint/eslint-plugin": "^5.16.0",
"@typescript-eslint/parser": "^5.16.0",

View File

@ -212,7 +212,8 @@
.octo-table-body {
display: flex;
flex-direction: column;
width: fit-content;
width: 100%;
height: 100%;
}
.octo-table-header,
@ -250,7 +251,8 @@
}
.table-row-container {
width: fit-content;
width: 100%;
height: 100%;
.octo-table-cell {
align-items: center;

View File

@ -1,6 +1,8 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback} from 'react'
import {FixedSizeList, ListChildComponentProps} from 'react-window';
import AutoSizer from 'react-virtualized-auto-sizer';
import {Card} from '../../blocks/card'
import {Board} from '../../blocks/board'
@ -26,14 +28,26 @@ type Props = {
const TableRows = (props: Props): JSX.Element => {
const {board, cards, activeView} = props
console.log(cards);
const onClickRow = useCallback((e: React.MouseEvent<HTMLDivElement>, card: Card) => {
props.onCardClicked(e, card)
}, [props.onCardClicked])
return (
<>
{cards.map((card, idx) => {
return (
const isItemLoaded = (index: number) => {
return index < cards.length;
};
const Item = ({index, style}: ListChildComponentProps) => {
const card = cards[index]
console.log(card)
if (isItemLoaded(index)) {
return (
<div
style={style}
key={card.id + card.updateAt}
>
<TableRow
key={card.id + card.updateAt}
board={board}
@ -46,14 +60,34 @@ const TableRows = (props: Props): JSX.Element => {
addCard={props.addCard}
isSelected={props.selectedCardIds.includes(card.id)}
focusOnMount={props.cardIdToFocusOnRender === card.id}
isLastCard={idx === (cards.length - 1)}
isLastCard={index === (cards.length - 1)}
onClick={onClickRow}
showCard={props.showCard}
readonly={props.readonly}
onDrop={props.onDrop}
/>)
})}
</>
/>
</div>
)
}
return null
}
return (
<AutoSizer>
{({height, width}) => (
<FixedSizeList
height={height}
itemCount={1828}
itemSize={44}
width={width}
>
{Item}
</FixedSizeList>
)}
</AutoSizer>
)
}