一、背景:表格性能瓶颈如何产生?
在广告平台管理后台中,表格场景极为常见:广告计划列表、投放记录、素材库、审批记录……
当记录量达到 1000+ 甚至 5000+ 时,性能问题愈加明显:
- 渲染卡顿(表格滚动不流畅)
- 加载缓慢(页面 freeze)
- 响应迟滞(操作无响应)
如何平衡体验与性能,成为中后台开发中的经典难题。
二、分页:最稳妥的传统解法
适用场景:数据量大、但用户访问集中在前几页
✅ 优点:
- 渲染数量受控(每页固定)
- 实现简单,兼容性好
❌ 缺点:
- 操作多(切换页)
- 不支持连续滚动体验
示例:
<n-data-table :columns="columns" :data="tableData" />
<n-pagination :page="page" @update:page="fetchData" />
数据按页请求:
const fetchData = async () => {
const res = await getAdPlans({ page: page.value })
tableData.value = res.data.list
}
三、懒加载:滚动加载下一页数据
适用场景:数据量中等、希望连续滚动
✅ 优点:
- 用户体验较流畅
- 不必加载全部数据
❌ 缺点:
- 滚动监听复杂,易出现重复请求或加载抖动
- 表格无法原生支持无限滚动
示例实现:
const onScroll = (e) => {
const bottom = e.target.scrollTop + e.target.clientHeight >= e.target.scrollHeight - 10
if (bottom && !loading.value && !finished.value) {
loadMore()
}
}
HTML 中绑定:
<div class="table-wrapper" @scroll="onScroll">
<n-data-table :data="tableData" />
</div>
四、虚拟列表:只渲染可见区域
适用场景:数据量极大、需要高性能展示
✅ 优点:
- 渲染性能极高
- 内存占用低
❌ 缺点:
- 表格功能限制多(如固定列、合并单元格)
- 与 UI 框架集成复杂
使用 vue-virtual-scroll-list 示例:
<VirtualList
:data-key="'id'"
:data-sources="data"
:data-component="RowRender"
:keeps="20"
/>
RowRender 是自定义行组件,样式需手动模拟 table 效果。
五、最佳实践对比
| 场景 | 推荐策略 |
|---|---|
| 数据 < 500 条 | 常规分页 |
| 数据 500-3000 条 | 懒加载分页 |
| 数据 3000+ 且频繁滚动 | 虚拟列表 |
| 表格功能复杂(排序、操作) | 分页 + 缓存 |
六、实战:广告列表的三次优化演进
第一版:一次性加载所有数据 → 卡顿严重
const res = await getAllPlans()
this.tableData = res.list // 卡到无法滚动
第二版:分页 + 后端接口
await getPlans({ page: 1, pageSize: 20 })
✅ 卡顿解决,但运营抱怨翻页不方便。
第三版:分页 + 缓存滑动窗口 + 懒加载切页
- 当前页数据保留
- 向前/向后预加载1页
- 滚动切换页,但数据源保持在本地缓存中
const planCache = new Map()
const fetchPage = async (p) => {
if (planCache.has(p)) return planCache.get(p)
const res = await getPlans({ page: p })
planCache.set(p, res.list)
return res.list
}
七、总结:渲染策略没有银弹,只有适配业务的最优解
在网易等平台型中后台系统中,前端工程师需要具备:
- 多种渲染策略的理解与落地能力
- 能够平衡用户体验与开发复杂度
- 提前设计好“性能预案”,而不是上线后亡羊补牢