【JavaScript】虚拟列表

58 阅读3分钟

前言

前端一次性拿到大量数据,再以列表的形式一次性全部渲染到界面上,是一件非常消耗性能的事情,势必会造成界面渲染慢、卡顿等现象。

因此,出于对用户体验和应用性能两方面权衡考虑,我们常用的优化方案主要有以下三种:

  • 分页加载
    • 优点:实现简单直接
    • 缺点:再切换页码或页尺寸的时候,可能会打断用户心流,体验不是最佳
  • 懒加载
    • 优点:实现难度不大,可以解决首屏的压力
    • 缺点:长时间加载数据,也同样会产生大量元素节点,从而影响应用性能(因为也没有处理过期节点的销毁问题)
  • 虚拟列表:是现代应用开发中一种流行方案
    • 优点:减少了首屏压力,长时间加载也不会有更多的性能负担

    • 缺点:实现单独较大。需要通过计算滚动视窗,每次只渲染部分元素

    • 成熟解决方案:react-virtualized、react-window 等

    • 什么是虚拟列表:

      虚拟列表是一种按需显示的技术。可以根据用户的滚动,不必渲染所有列表项,而只渲染可视区域的一部分列表元素的技术

一、原理分析

核心原理:一直渲染一定数量的列表项,从而提升渲染性能。核心在于通过计算出 startIndex(起始索引) 和 endIndex(结束索引) ,只展示视口以内的元素

当我们滚动到一个元素离开可视区范围内时,就去掉上缓冲区顶上的一个元素,然后再下缓冲区增加一个元素

组成

  • 滚动容器元素:滚动容器元素是 window 对象,或某个元素(div)能在内部产生横向或纵向的滚动的这个元素

  • 可滚动区域:滚动容器元素的内部内容区域。假设有100条数据,每个列表项的高度是50,那么可滚动的区域的高度是 100*50

    组成:上缓冲区 + 可视区域 + 下缓冲区

  • 可视区域:滚动容器元素的的视觉可见区域。

二、具体实现

2.1 元素高度固定的虚拟列表

示例演示

实现原理

1)设置滚动容器的宽高等样式

2)计算全部数据撑起的盒子(称之为container)的高度。目的是为了撑起盒子,让用户能进行滚动操作

3)计算出可视区的起始索引、上缓冲区的起始索引和下缓冲区的结束索引

4)采用绝对定位,计算上缓冲区到下缓冲区之间的每一个元素在contianer中的top值,只有知道top值才能让元素出现在可视区内。

5)将上缓冲区到下缓冲区的元素塞到container中。

image.png

2.2 元素高度不固定的虚拟列表

2.3

参考