如果后端返回 10 万条数据,直接渲染到前端会导致严重的性能问题(卡顿、崩溃)。你需要用 分页、虚拟列表、分批加载等方式优化,具体方法如下:
1. 后端分页(最优方案 )
让后端分页返回数据,前端按需请求,每次只获取一小部分数据。
适用场景
- API 支持分页
- 数据量大,不需要一次性加载所有数据
代码示例
const fetchData = async (page: number, pageSize: number) => {
const response = await fetch(`/api/data?page=${page}&pageSize=${pageSize}`);
const result = await response.json();
return result.data;
};
useEffect(() => {
fetchData(1, 50).then((data) => setTableData(data));
}, []);
后端示例(Node.js/Express)
app.get('/api/data', (req, res) => {
const { page, pageSize } = req.query;
const startIndex = (page - 1) * pageSize;
const paginatedData = allData.slice(startIndex, startIndex + pageSize);
res.json({ data: paginatedData });
});
前端只加载当前页数据,大幅优化性能。
2. 虚拟列表(适用于大表格/列表 )
如果必须一次性获取所有数据,使用 虚拟列表 渲染可视范围内的元素,减少 DOM 负担。
适用场景
- 数据一次性获取,但只需要部分展示(如长列表)
- 使用 react-window 或 react-virtualized
代码示例(react-window)
import { FixedSizeList as List } from 'react-window';
const VirtualList = ({ data }) => (
{({ index, style }) => {data[index].name}}
);
export default VirtualList;
只渲染可见的元素,滚动时动态加载,提高性能!
3. 前端懒加载(滚动加载 / 分批渲染)
如果 API 不能分页,可以前端手动分批渲染,避免一次性渲染 10 万条数据。
适用场景
- 数据必须一次性获取
- 列表或表格需要逐步加载
代码示例
const [visibleData, setVisibleData] = useState([]);
const batchSize = 500;
useEffect(() => {
let index = 0;
const loadMore = () => {
if (index >= allData.length) return;
setVisibleData((prev) => [...prev, ...allData.slice(index, index + batchSize)]);
index += batchSize;
requestAnimationFrame(loadMore);
};
loadMore();
}, []);
逐步渲染数据,避免页面卡顿。
4. Web Worker 处理大数据
如果需要前端计算(如排序、筛选),可以用 Web Worker 在后台线程执行,避免 UI 卡死。
代码示例
// worker.js
self.onmessage = function (e) {
const sortedData = e.data.sort((a, b) => a.value - b.value);
self.postMessage(sortedData);
};
const worker = new Worker("worker.js");
worker.postMessage(bigData);
worker.onmessage = function (e) {
setTableData(e.data);
};
异步计算,不影响主线程渲染。
总结
方法 | 适用场景 | 优势 | 适配性 |
后端分页 | API 支持分页 | 最佳性能,减少数据传输 | |
虚拟列表 | 大量数据但可视区域有限 | 仅渲染可见部分 | |
懒加载 | API 无法分页 | 逐步加载,减少瞬时渲染压力 | |
Web Worker | 需处理大数据 | 异步计算,不影响 UI |
如果 API 支持分页,建议用后端分页;如果必须一次性获取数据,推荐虚拟列表或懒加载。