虚拟列表 vs 分页 vs 懒加载:中后台大数据渲染的最佳实践

141 阅读2分钟

一、背景:表格性能瓶颈如何产生?

在广告平台管理后台中,表格场景极为常见:广告计划列表、投放记录、素材库、审批记录……

当记录量达到 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
}

七、总结:渲染策略没有银弹,只有适配业务的最优解

在网易等平台型中后台系统中,前端工程师需要具备:

  • 多种渲染策略的理解与落地能力
  • 能够平衡用户体验与开发复杂度
  • 提前设计好“性能预案”,而不是上线后亡羊补牢