Virtualize 组件适用于大数据量、高频滚动、结构复杂场景,需容器有固定高度且数据源支持分页;静态列表用 Items+ItemSize,海量数据用 ItemsProvider 异步加载。

Blazor 的 Virtualize 组件能显著减少长列表的 DOM 元素数量,只渲染可视区域内的项,从而大幅降低内存占用和重绘开销——它不是“懒加载”,而是“按需渲染”。
什么时候该用 Virtualize?
适用于数据量大(比如上千条)、滚动频繁、且每项结构较复杂的场景。例如用户管理列表、日志查看器、实时消息流。如果只有几十条数据,或内容极简(如纯文本 ID),反而可能因虚拟化开销得不偿失。
关键判断点:
- 列表高度固定或可预估(Virtualize 需要容器有明确高度)
- 数据源支持分页/跳转(如实现了
IAsyncEnumerable或提供LoadData方法) - 不需要对所有项做全局操作(如全选、导出全部),或这类操作可单独处理
基础用法:绑定静态集合
最简单的场景是渲染已加载完成的本地列表。注意必须设置 ItemSize(单位像素),让组件估算可视区域能容纳几项:
@context.Name (@context.Id)
说明:
-
ItemSize尽量准确。若行高不均,可用平均值,但滚动时可能出现短暂空白或重叠 -
Items是IReadOnlyList,适合一次性加载完的数据 - 避免在
ItemContent中写复杂逻辑或频繁触发重渲染的代码
进阶用法:异步按需加载(分页式虚拟化)
当数据总量极大(如百万级)时,应配合服务端分页。用 ItemsProvider 替代 Items:
Loading...
核心要点:
-
LoadItemsAsync是一个Func,接收请求范围(>> StartIndex和Count),返回对应数据和总条数 - 服务端接口需支持“从第 N 条取 M 条”,并返回总数(用于滚动条比例计算)
- 首次加载会触发多次请求(为填充缓冲区),后续滚动基本单次请求即可
优化细节与避坑提示
Virtualize 效果好不好,细节决定成败:
- 确保父容器有固定高度(如
style="height: 600px; overflow-y: auto;"),否则无法计算可视区域 - 避免在
ItemContent中使用@key绑定动态值(如索引),改用稳定标识(如@context.Id) - 慎用 CSS 动画或过渡效果——虚拟化会复用 DOM 节点,动画状态可能错乱
- 测试滚动到末尾时是否卡顿;若卡,检查
ItemsProvider是否阻塞、数据库查询是否加了合适索引
基本上就这些。Virtualize 不是银弹,但它在正确场景下能让 Blazor 列表体验接近原生应用。用好它,关键在理解“只渲染可见部分”这个前提,然后围绕这个前提设计数据获取和 UI 结构。











