前端虚拟列表实现:别再渲染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

Bug记录:vscode中copilot登录github时报错——尚未完成授权此扩展使用 GitHub 的操作。

Bug记录:vscode中copilot登录github时报错——尚未完成授权此扩展使用 GitHub 的操作。

尝试了很多网上的方法无果,还是选择寻求deepseek的帮助,如下: 在VS Code中遇到“尚未完成授权此扩展使用 GitHub 的操作”错误时,可以按照以下步骤解决: 1. 重新启动授权流程 * 在VS Code中,按下 Ctrl+Shift+P 打开命令面板。 * 输入 GitHub: Sign In 并选择该命令。 * 按照提示在浏览器中完成授权流程。如果浏览器未自动打开,手动访问显示的链接并输入提供的验证码。 2. 清除GitHub的旧授权 * 登录GitHub,进入 Settings → Applications → Authorized OAuth Apps。 * 找到并撤销与 Visual Studio Code 或 GitHub for VSCode 相关的授权。 * 返回VS Code,重新尝试登录。 3. 退出并清除VS

openclaw使用llama.cpp 本地大模型部署教程

openclaw使用llama.cpp 本地大模型部署教程

openclaw使用llama.cpp 本地大模型部署教程 本教程基于实际操作整理,适用于 Windows WSL2 环境 全程使用 openclaw 帮我搭建大模型 一、环境准备 1. 硬件要求 显卡推荐模型显存占用GTX 1050 Ti (4GB)Qwen2.5-3B Q4~2.5GBRTX 4060 (8GB)Qwen2.5-7B Q4~5GBRTX 4090 (24GB)Qwen2.5-32B Q4~20GB 2. 安装编译工具(WSL Ubuntu) sudoapt update sudoaptinstall -y cmake build-essential 二、下载和编译 llama.cpp

DeepSeek-R1-Distill-Llama-8B在Ollama上的最佳实践

DeepSeek-R1-Distill-Llama-8B在Ollama上的最佳实践 你是否试过在本地快速跑起一个真正擅长数学推理和代码生成的开源大模型,既不用配CUDA环境,也不用写几十行部署脚本?DeepSeek-R1-Distill-Llama-8B 就是这样一个“开箱即用但能力不妥协”的选择——它不是轻量玩具,而是经过严格蒸馏、在AIME和MATH等硬核基准上稳定超越GPT-4o的8B级推理模型。而Ollama,正是让它从镜像变成你日常生产力工具最平滑的桥梁。 本文不讲抽象原理,不堆参数表格,只聚焦一件事:如何在Ollama中真正用好这个模型——从零启动、高效提问、规避常见陷阱、榨取它在数学推导、代码生成和逻辑分析上的全部潜力。 我们全程基于ZEEKLOG星图镜像广场提供的预置镜像 DeepSeek-R1-Distill-Llama-8B,所有操作均可在浏览器中完成,无需命令行、不装依赖、不碰Docker。哪怕你昨天才第一次听说“大模型”,今天也能跑通一条完整的推理链。 1. 为什么是DeepSeek-R1-Distill-Llama-8B?——能力与实用的平衡点 很

Buzz语音转文字离线免费版安装使用(含Whisper最新模型)

Buzz语音转文字离线免费版安装使用(含Whisper最新模型)

简介: Buzz1.2.0(2024年12月24日更新的,是2025年7月最新版本) Buzz有python编写的, 在您的个人计算机上离线转录和翻译音频。由 OpenAI 的 Whisper 提供支持。 应用场景: 歌曲提取歌词,音频/视频提取文字 软件下载(windows为例): github下载地址: Release v1.2.0 · chidiwilliams/buzzhttps://github.com/chidiwilliams/buzz/releases/tag/v1.2.0 文章最后有百度云盘离线下载地址(含模型) 软件安装: exe文件直接安装即可 软件使用: 当前支持的模型: 如果没有【查看文件位置】 C:\Users\用户\AppData\Local\Buzz\Buzz\