【study】虚拟滚动加载原理是什么

123 阅读2分钟
  1. 虚拟滚动:
  • 虚拟滚动是一种优化列表渲染性能的技术,特别适合用于渲染大量数据的场景,虚拟滚动的核心思想是只渲染可视区域内的列表项,以及刚好在视口边界之外的少量缓冲区域,当用户滚动时,不在视口中的元素会被移除或隐瞒,新的元素会被动态加载和渲染。
  1. 原理
  • 可视窗口:只渲染用户当前可见区域的元素
  • 列表总高度:将整个列表的高度进行虚拟计算,并通过css设置
  • 位置偏移:视同元素的top、translateY等属性来表示元素在滚动区域的位置
  1. 实现步骤
  • 初始化虚拟列表的容器和内容
  • 监听滚动事件,计算当前可视区域的元素
  • 动态渲染或移除元素
  1. 简单的js实现
// 定义一个基本的 HTML 结构
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>虚拟滚动示例</title>
  <style>
    #scroll-container {
      height: 400px;
      overflow-y: auto;
      border: 1px solid #ccc;
      position: relative;
    }
    .item {
      height: 50px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-bottom: 1px solid #eee;
      position: absolute;
      width: 100%;
    }
  </style>
</head>
<body>
  <div id="scroll-container">
    <div id="scroll-content"></div>
  </div>

  <script src="virtual-scroll.js"></script>
</body>
</html>

//  (virtual-scroll.js)

// 实现虚拟滚动的核心逻辑。

document.addEventListener('DOMContentLoaded', function() {
  const totalItems = 100000; // 总数据数量
  const itemHeight = 50; // 每个项的高度
  const container = document.getElementById('scroll-container');
  const content = document.getElementById('scroll-content');
  const visibleItemsCount = Math.floor(container.clientHeight / itemHeight);
  const buffer = 5; // 缓冲区
  const totalHeight = totalItems * itemHeight;
  
  let topIndex = 0;
  
  // 设置列表总高度、为容器内的内容设置一个足够大的高度,来产生滚动条
  content.style.height = `${totalHeight}px`; 

  // 渲染可视区域内的元素
  function renderVisibleItems() {
    const start = topIndex;
    const end = Math.min(topIndex + visibleItemsCount + buffer, totalItems);
    
    content.innerHTML = '';
    for (let i = start; i < end; i++) {
      const item = document.createElement('div');
      item.classList.add('item');
      item.style.top = `${i * itemHeight}px`;
      item.textContent = `Item ${i + 1}`;
      content.appendChild(item);
    }
  }

 // 监听滚动事件
  container.addEventListener('scroll', function() {
    const scrollTop = container.scrollTop;
    topIndex = Math.floor(scrollTop / itemHeight);
    renderVisibleItems();
  });

  renderVisibleItems(); // 初始化渲染
});

  1. 优点
  • 性能优化:大幅减少了DOM节点的数量,避免了因渲染大量元素导致的性能问题
  • 用户体验:保持了良好的滚动响应速度和流畅度
  1. 应用场景
  • 大量数据的渲染、如表格数据、长列表、消息列表等