前端虚拟列表实现:别再渲染10000个DOM节点了

前端虚拟列表实现:别再渲染10000个DOM节点了

前端虚拟列表实现:别再渲染10000个DOM节点了

毒舌时刻

这代码写得跟网红滤镜似的——仅供参考。

各位前端同行,咱们今天聊聊前端虚拟列表。别告诉我你还在一次性渲染10000个列表项,那感觉就像把10000本书全部摆在桌面上——既占地方又难找。

为什么你需要虚拟列表

最近看到一个项目,一个下拉列表有5000个选项,全部渲染导致页面卡死,我差点当场去世。我就想问:你是在做列表还是在做性能杀手?

反面教材

// 反面教材:一次性渲染所有数据 function BigList({ items }) { return ( <ul style={{ height: '400px', overflow: 'auto' }}> {items.map(item => ( <li key={item.id} style={{ height: '50px' }}> {item.name} </li> ))} </ul> ); } // 使用 <BigList items={Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` }))} /> // 浏览器:我太难了 

毒舌点评:这代码,我看了都替浏览器着急。渲染10000个DOM节点,你是想让用户的电脑变成暖炉吗?

前端虚拟列表的正确姿势

1. 基础虚拟列表实现

// 正确姿势:基础虚拟列表 import { useState, useRef, useMemo, useCallback } from 'react'; function VirtualList({ items, itemHeight, containerHeight }) { const [scrollTop, setScrollTop] = useState(0); const containerRef = useRef(null); // 计算可见区域 const visibleCount = Math.ceil(containerHeight / itemHeight); const totalHeight = items.length * itemHeight; // 计算起始和结束索引 const startIndex = Math.floor(scrollTop / itemHeight); const endIndex = Math.min(startIndex + visibleCount + 1, items.length); // 获取可见项 const visibleItems = useMemo(() => { return items.slice(startIndex, endIndex); }, [items, startIndex, endIndex]); // 偏移量 const offsetY = startIndex * itemHeight; const handleScroll = useCallback((e) => { setScrollTop(e.target.scrollTop); }, []); return ( <div ref={containerRef} style={{ height: containerHeight, overflow: 'auto' }} onScroll={handleScroll} > <div style={{ height: totalHeight, position: 'relative' }}> <div style={{ transform: `translateY(${offsetY}px)` }}> {visibleItems.map((item, index) => ( <div key={item.id} style={{ height: itemHeight }} className="virtual-list-item" > {item.name} </div> ))} </div> </div> </div> ); } // 使用 function App() { const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` })); return ( <VirtualList items={items} itemHeight={50} containerHeight={400} /> ); } 

2. 使用react-window

// 正确姿势:使用react-window import { FixedSizeList as List } from 'react-window'; function VirtualList({ items }) { const Row = ({ index, style }) => ( <div style={style} className="list-item"> {items[index].name} </div> ); return ( <List height={400} itemCount={items.length} itemSize={50} > {Row} </List> ); } // 使用 function App() { const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` })); return <VirtualList items={items} />; } 

3. 使用vue-virtual-scroller

<!-- Vue3中使用vue-virtual-scroller --> <template> <RecycleScroller :items="items" :item-size="50" key-field="id" v-slot="{ item }" > <div> {{ item.name }} </div> </RecycleScroller> </template> <script setup> import { RecycleScroller } from 'vue-virtual-scroller'; import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'; const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` })); </script> <style> .scroller { height: 400px; } .item { height: 50px; display: flex; align-items: center; padding: 0 20px; } </style> 

毒舌点评:早这么写,你的列表早流畅了。别告诉我你还在渲染10000个DOM节点,那你还是趁早去用分页吧。

实战技巧:虚拟列表指南

1. 虚拟列表原理

  1. 只渲染可见项:只渲染视口内的元素
  2. 计算偏移量:通过transform移动内容
  3. 动态高度支持:预估高度或动态计算

2. 最佳实践

  1. 固定高度:优先使用固定高度,性能好
  2. 缓冲区域:上下多渲染几个item,避免白屏
  3. 滚动优化:使用requestAnimationFrame

最后想说的

虚拟列表不是炫技,是性能优化。别再渲染10000个DOM节点了——虚拟化一下,你的应用会飞起来。

虚拟列表就像图书馆的检索系统,不需要把所有书都摆在桌上,只需要展示你想看的那几本。别做图书搬运工,做图书管理员。

Read more

DeepSeek-R1-Distill-Llama-8B效果实测:CodeForces评分1205分背后——算法题时间复杂度分析能力验证

DeepSeek-R1-Distill-Llama-8B效果实测:CodeForces评分1205分背后——算法题时间复杂度分析能力验证 1. 模型介绍与测试背景 DeepSeek-R1-Distill-Llama-8B是DeepSeek团队推出的推理模型系列中的一员,这个8B参数的模型是从更大的DeepSeek-R1模型蒸馏而来。在众多基准测试中,该模型展现出了令人印象深刻的推理能力,特别是在CodeForces编程竞赛平台上获得了1205分的评分。 这个评分意味着什么?在编程竞赛中,1205分通常对应着能够稳定解决Div.2的A、B题和部分C题的水平,这要求模型不仅要能理解问题描述,还要具备算法思维和时间复杂度分析能力。对于一个人工智能模型来说,这是相当不错的成绩。 2. 时间复杂度分析能力测试 2.1 测试方法与标准 为了验证DeepSeek-R1-Distill-Llama-8B的时间复杂度分析能力,我们设计了一系列测试题目,涵盖不同难度级别和算法类型。测试标准包括: * 问题理解准确性:模型是否能正确理解题目要求 * 算法选择合理性:选择的算法是否适合问

llama.cpp重大更新:自带Web UI,性能超越Ollama,本地大模型部署新选择!

llama.cpp重大更新:自带Web UI,性能超越Ollama,本地大模型部署新选择!

Ollama 背后执行推理的核心技术其实是由 llama.cpp 承担的,GGUF 模型格式也是由 llama.cpp 的作者所开发。 现在 llama.cpp 迎来重大更新,它也有了自己的 Web UI,我测试了安装部署和自行打包,很多地方确实比 Ollama 还有方便好用。 官方介绍,优势如下: * 完全免费、开源且由社区驱动 * 在所有硬件上表现出色 * 高级上下文和前缀缓存 * 并行和远程用户支持 * 极其轻量级且内存高效 * 充满活力且富有创造力的社区 * 100% 隐私 使用之前需要先安装 llama.cpp server 我还是喜欢命令行直接安装 ## Winget (Windows)winget install llama.cpp## Homebrew (Mac and Linux)brew install llama.

全网最靠谱有效!!!解决新机型 Copilot 键替代右 Ctrl 键问题

全网最靠谱有效!!!解决新机型 Copilot 键替代右 Ctrl 键问题

引路者👇: 前言 一、先搞懂:Copilot 键原本是干嘛的? 二、核心解决方案:用微软官方工具 PowerToys 映射 步骤 1:下载安装 PowerToys 步骤 2:开启 “键盘管理器” 功能 步骤 3:添加 “快捷键映射”(关键步骤) 步骤 4:测试功能是否生效 三、注意事项:确保映射长期生效 四、常见问题排查(避坑指南) 五、总结 前言         作为一名长期依赖右 Ctrl 键进行操作的程序员 / 办公用户,今年换了新的拯救者笔记本后,发现键盘上原本的右 Ctrl 键被一个陌生的 “Copilot 键” 取代了。日常用 “Ctrl+

LLaMA Factory操作界面微调时报disable multiprocessing.

LLaMA Factory操作界面微调时报disable multiprocessing.

LLaMA Factory操作界面微调时报disable multiprocessing 陈述问题 由于显卡性能不强,微调模型时会报以下下错误,GPU内存或系统内存不足,尤其在处理大规模数据或大模型时,子进程因内存溢出崩溃。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "G:\project\LLaMA-Factory\src\llamafactory\data\converter.py", line 420, in align_dataset return dataset.map( ^^^^^^^^^^^^ File "C:\Python312\Lib\site-packages\datasets\arrow_dataset.py", line 557, in wrapper out: Union["Dataset", "DatasetDict&