为 SCADA 设备列表实现虚拟列表,优化渲染性能

This commit is contained in:
JIANG
2025-10-29 17:24:35 +08:00
parent a5954624a0
commit 09d037fd5a
3 changed files with 144 additions and 105 deletions

36
package-lock.json generated
View File

@@ -37,7 +37,7 @@
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-icons": "^5.5.0",
"react-window": "^2.2.2",
"react-window": "^1.8.10",
"tailwindcss": "^4.1.13"
},
"devDependencies": {
@@ -46,6 +46,7 @@
"@types/node": "^20",
"@types/react": "^19.1.0",
"@types/react-dom": "^19.1.0",
"@types/react-window": "^1.8.8",
"cross-env": "^7.0.3",
"eslint": "^8",
"eslint-config-next": "^15.0.3",
@@ -7992,6 +7993,16 @@
"@types/react": "*"
}
},
"node_modules/@types/react-window": {
"version": "1.8.8",
"resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz",
"integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/unist": {
"version": "2.0.11",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
@@ -14590,6 +14601,12 @@
"node": ">= 0.6"
}
},
"node_modules/memoize-one": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==",
"license": "MIT"
},
"node_modules/merge-descriptors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
@@ -16462,13 +16479,20 @@
}
},
"node_modules/react-window": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/react-window/-/react-window-2.2.2.tgz",
"integrity": "sha512-kvHKwFImKBWNbx2S87NZOhQhAVkBthjmnOfHlhQI45p3A+D+V53E+CqQMsyHrxNe3ke+YtWXuKDa1eoHAaIWJg==",
"version": "1.8.10",
"resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz",
"integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.0.0",
"memoize-one": ">=3.1.1 <6"
},
"engines": {
"node": ">8.0.0"
},
"peerDependencies": {
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
"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/readable-stream": {

View File

@@ -42,7 +42,7 @@
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-icons": "^5.5.0",
"react-window": "^2.2.2",
"react-window": "^1.8.10",
"tailwindcss": "^4.1.13"
},
"devDependencies": {
@@ -51,6 +51,7 @@
"@types/node": "^20",
"@types/react": "^19.1.0",
"@types/react-dom": "^19.1.0",
"@types/react-window": "^1.8.8",
"cross-env": "^7.0.3",
"eslint": "^8",
"eslint-config-next": "^15.0.3",

View File

@@ -12,7 +12,6 @@ import {
Box,
Paper,
Typography,
List,
ListItem,
ListItemButton,
ListItemText,
@@ -39,6 +38,7 @@ import {
Clear,
DeviceHub,
} from "@mui/icons-material";
import { FixedSizeList } from "react-window";
import { useMap } from "@app/OlMap/MapComponent";
import { GeoJSON } from "ol/format";
@@ -452,9 +452,22 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
</Typography>
</Box>
) : (
<List dense sx={{ p: 0 }}>
{filteredDevices.map((device, index) => (
<React.Fragment key={device.id}>
<FixedSizeList
height={400}
itemCount={filteredDevices.length}
itemSize={80}
width="100%"
>
{({
index,
style,
}: {
index: number;
style: React.CSSProperties;
}) => {
const device = filteredDevices[index];
return (
<div style={style}>
<ListItem disablePadding>
<ListItemButton
selected={activeSelection.includes(device.id)}
@@ -551,9 +564,10 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
{index < filteredDevices.length - 1 && (
<Divider variant="inset" />
)}
</React.Fragment>
))}
</List>
</div>
);
}}
</FixedSizeList>
)}
</Box>
</Collapse>