【全网最通俗易懂】虚拟列表2-(缓冲区篇):渲染十万条数据不卡顿(附demo和源码)

476 阅读2分钟

大家好,我是前端架构师,关注微信公众号【程序员大卫】领取免费前端精品资料。

虚拟列表-示例.gif

这是虚拟列表系列的第二篇文章,这次将为虚拟列表添加缓冲区。如果你还没看过上一篇内容,可以先点击这里了解:【全网最通俗易懂】虚拟列表:渲染十万条数据不卡顿(附demo和源码)

在线地址预览

本文主要讲解如何为虚拟列表添加缓冲区的功能。下一篇将是虚拟列表系列的终章,我们将探讨如何实现不定高虚拟列表动态监听高度等更高级的技术。

背景

为什么虚拟列表需要添加缓冲区?

这是因为在快速上下滚动时,可能会出现部分内容显示不全的情况。缓冲区的存在可以有效避免这一问题。

实现方案

我们假设每项的高度固定为 100px,同时缓冲区在可视区域上下各有 2 项。

以下是两种情况的处理逻辑:

情况一:滚动未超过缓冲区范围

假设当前的滚动高度为 240px,此时滚动的位置尚未超出缓冲区范围,因此无需设置渲染区域的偏移量(offset)。渲染效果如下:

情况二:滚动超过缓冲区范围

假设当前滚动高度为 440px,下面对两种渲染效果进行对比:

1.普通列表的滚动效果

正常情况下,滚动至 440px 时,视觉效果如下:

2.未设置偏移量的缓冲区滚动效果

如果不设置偏移量,渲染效果会显得不自然,与普通滚动效果不一致:

虚拟列表-未设置偏移量.png

为了使视觉效果与普通滚动一致,我们需要为渲染区域设置 200px 的偏移量。调整后的效果如下:

核心代码实现

结合上文的分析,我们可以看出:与未设置缓冲区的虚拟列表相比,添加缓冲区后主要差异在于 起始索引结束索引 的计算。其余逻辑保持不变。

以下是实现代码:

// 计算当前可视范围的顶部索引
const topIndex = computed(() => Math.floor(scrollTop.value / props.itemSize));

// 当前滚动位置对应的起始索引
const startIndex = computed(() =>
  Math.max(0, topIndex.value - props.bufferCount)
);

// 当前滚动位置对应的结束索引,基于起始索引和可视数量
const endIndex = computed(() =>
  Math.min(
    totalItemCount.value - 1,
    topIndex.value + visibleCount.value + props.bufferCount
  )
);

源码

github.com/zm8/wechat-…

最后

点赞👍 + 关注➕ + 收藏❤️ = 学会了🎉。

更多优质内容关注公众号,@前端大卫。