虚拟滚动的方案
1. 为什么需要使用虚拟滚动技术?
在前端开发中,会碰到一些不能使用分页方式来加载列表数据的业务形态,我们称这种列表叫做长列表。比如ant-design下拉框的数据项,如果直接将所有的数据都生成dom,页面会非常卡顿。
因此,虚拟滚动的核心思想就是只加载可视区域内需要的列表项,当滚动发生时,动态通过计算获得可视区域内的列表项,并将非可视区域内存在的列表项删除。
2. 关键技术点?
dom结构上,需要一个视窗容器(visualContainer)、一个让视窗具备滚动条的占位子元素(placeholderDom),一个呈现可视区域数据的容器(dataContainer);
根据视窗高度和行高(itemHeight),可得出视窗能显示的条数(visualNum);
根据行高和总数据量,可得出占位子元素的高度(totalHeight);
根据滚动条的位置/行高,可得出当前应显示数组的开始下标(startIndex),通过startIndex+visualNum,得出数组的结束下标(endIndex);使用数组的slice(startIndex,endIndex)取出需要显示的数据(displayData);
displayData的数据显示在dataContainer中,dataContainer在默认情况下相对container的坐标始终是(0,0),当视窗滚动时,需要移动dataContainer的位置,移动的位置(startOffset) = (新的startIndex - 上一次的startIndex)*itemHeight;
为了防止页面整体回流,将dataContainer的position设为absolute,并使用css3的transform:tanslateY来开启gpu加速;
为了避免快速滚动时频繁更新dom导致页面出现空白、卡顿,需要使用window.requestAnimationFrame方法来处理滚动回调;
3. 具体实现
缺点:只要有滚动就重新计算需要取出的数据,导致dom频繁更新
复杂版
使用了滚动条分页概念,当滚动条到达边界数据时,计算新一页的数据,同时为了让边界数据前后可浏览器,一般会在前后各增加一页缓冲数据。