LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

大量条目和无限滚动场景中用到的虚拟列表技术是什么原理?

freeflydom
2024年8月6日 14:55 本文热度 792

虚拟列表(Virtual List)技术是一种优化长列表渲染性能的技术,特别适用于处理大量数据的场景。其主要原理是通过“虚拟化”列表内容,只渲染用户视口(可视区域)内的元素,而不是渲染整个列表。这样可以显著减少 DOM 元素的数量,提高页面性能和响应速度。

虚拟列表的原理

视口范围渲染:

仅渲染可视区域:虚拟列表只渲染当前用户视口内的列表项,即用户能够看到的部分。这减少了 DOM 元素的数量,避免了性能瓶颈。

动态加载:当用户滚动时,虚拟列表动态地卸载视口外的元素,并加载新的视口内的元素,保持 DOM 的高效性。

占位元素:

占位空间:为了保持列表的滚动位置和正确的布局,虚拟列表会使用占位元素(虚拟的空白元素)来表示未渲染部分的高度或宽度。这样可以确保滚动条的高度与实际内容长度一致。

滚动计算:通过计算已渲染项的总高度和占位元素的高度,虚拟列表可以模拟整个列表的实际高度,提供正确的滚动行为。

元素复用:

重用组件:在虚拟列表中,通常会重用相同的组件实例来渲染不同的数据项,从而减少 DOM 操作的开销。

虚拟化列表项:仅创建当前视口所需的 DOM 元素实例,避免创建过多的无用 DOM 节点。

实现虚拟列表的步骤

计算视口高度和滚动位置:

计算当前视口的高度,以及滚动条的位置,以确定哪些数据项需要渲染。

创建占位元素:

根据总数据量和单个数据项的高度,创建占位元素来模拟整个列表的高度,使滚动条显示正确的长度。

渲染可视区域元素:

根据当前滚动位置计算需要渲染的数据项,并在 DOM 中插入这些元素。

处理滚动事件:

监听滚动事件,动态计算需要渲染的内容和更新视口内的元素。当用户滚动时,调整可视区域内的元素,并更新占位元素。

优化性能:

节流/防抖:在处理滚动事件时,使用节流(throttling)或防抖(debouncing)技术来减少处理频率,避免性能问题。

异步渲染:将渲染操作拆分成异步任务,避免阻塞主线程。

例子与应用

前端框架中的虚拟列表实现

React Virtualized、React Window:这两个库用于在 React 中实现虚拟列表,提供了简单易用的 API 来管理虚拟化列表的渲染。

Vue Virtual Scroll List:为 Vue 提供虚拟滚动功能,优化长列表的渲染性能。

实现示例(原生 JavaScript)

<!DOCTYPE html> 

<html>

<head> 

<meta charset="UTF-8"> 

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style> 

#container { 

height: 400px; /* 视口高度 */

overflow-y: auto; /* 启用滚动 */ 

position: relative; 

#content { 

position: absolute; width: 100%;

.item { 

height: 50px; /* 每个项的高度 */ 

border-bottom: 1px solid #ddd; 

</style> 

</head> 

<body> 

<div id="container">

<div id="content"></div>

</div>

<script> 

const container = document.getElementById('container'); 

const content = document.getElementById('content'); 

const itemHeight = 50; // 每个项的高度 

const itemCount = 1000; // 数据项总数 

const viewportHeight = container.clientHeight; // 视口高度 

// 计算总高度 

const totalHeight = itemCount * itemHeight; 

content.style.height = `${totalHeight}px`; 

// 渲染项 

function renderItems() { 

const scrollTop = container.scrollTop; 

const startIndex = Math.floor(scrollTop / itemHeight); 

const endIndex = Math.min(itemCount - 1, Math.ceil((scrollTop + viewportHeight) / itemHeight)); 

let html = ''; 

for (let i = startIndex; i <= endIndex; i++) { 

    html += `<div>Item ${i}</div>`; 

}

content.innerHTML = html; 

container.addEventListener('scroll', () => {

renderItems(); 

}); 

// 初始渲染

renderItems(); 

</script> 

</body> 

</html>

实现示例(React)

在 React 中,可以使用现成的库如 React Window 或 React Virtualized 实现虚拟列表,或者自己实现:

import React, { useState, useEffect, useRef } from 'react'; 

const VirtualList = ({ itemCount, itemHeight }) => {

const [visibleItems, setVisibleItems] = useState([]); 

const containerRef = useRef(null); 

useEffect(() => {

    const handleScroll = () => { 

        const container = containerRef.current; 

        const scrollTop = container.scrollTop; 

        const viewportHeight = container.clientHeight; 

        const startIndex = Math.floor(scrollTop / itemHeight); 

        const endIndex = Math.min(itemCount - 1, Math.ceil((scrollTop + viewportHeight) / itemHeight)); 

        const items = []; 

        for (let i = startIndex; i <= endIndex; i++) { 

        items.push(i); 

        } 

        setVisibleItems(items);

    }; 

    containerRef.current.addEventListener('scroll', handleScroll);

    handleScroll(); // Initial render

    return () => { 

    containerRef.current.removeEventListener('scroll', handleScroll); };

}, [itemCount, itemHeight]); 

const totalHeight = itemCount * itemHeight; 

return ( 

    <div ref={containerRef} style={{ height: '400px', overflowY: 'auto', position: 'relative' }}> 

        <div style={{ height: `${totalHeight}px`, position: 'relative' }}> 

            {visibleItems.map(item => ( 

            <div key={item} style={{ height: `${itemHeight}px`, borderBottom: '1px solid #ddd' }}> 

                Item {item} 

            </div>

            ))} 

        </div> 

    </div> 

    ); 

}; 

export default VirtualList;

场景应用

长数据列表:适用于需要显示大量条目的场景,例如电子邮件列表、评论列表、数据表格等

无限滚动:与虚拟列表技术结合,支持无限滚动加载数据,提升用户体验

总结

虚拟列表技术通过仅渲染视口内的内容、使用占位元素模拟总高度、动态加载和卸载元素来优化性能。它特别适用于处理大量数据的场景,可以显著提高渲染效率和用户体验。在现代前端框架中,许多库和工具都提供了虚拟列表的实现,帮助开发者轻松集成这一技术


来源:https://juejin.cn/post/7399851256225873929 作者:一曲高山流水



该文章在 2024/8/6 15:08:36 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved