为什么用了虚拟滚动后列表滚动还是卡顿?
我在一个Vue项目里用v-for渲染2000条列表项,滚动特别卡。试过vue-virtual-scroller但没改善,控制台没报错,FPS还是掉到30以下。这是我的代码:
<template>
<VirtualList :size="50" :estimated="2000">
<div v-for="item in items" :key="item.id">
{{ item.content }}
</div>
</VirtualList>
</template>
检查过元素高度计算没问题,也设置了固定高度容器。难道是key没写对?或者虚拟滚动有其他隐藏配置没设置?
:wrap-size="containerHeight"或者检查下父容器有没有设置固定高度。另外v-for套在VirtualList里面可能渲染没拦截住,改成v-for包裹VirtualList试试:先说你的代码问题:
你虽然套了个
,但里面items都渲染出来了,**虚拟滚动压根没生效**。vue-virtual-scroller的组件是需要每个 item 被单独包裹成一个组件或者用v-for在内部循环生成 item 的。正确写法应该是这样:
注意点:
-
要通过data传入列表数据- 用
#default="{ item }"的方式来渲染每一项- 每个 item 的高度尽量统一,或准确提供
item-size或使用dynamic模式(但会损耗性能)- 如果内容高度不一致,记得加
:dynamic="true",但 FPS 可能还是会受影响FPS 掉到 30 以下,说明渲染压力大,除了正确使用虚拟滚动外,还可以检查:
- 列表项里有没有复杂的计算属性或嵌套组件
- 使用
key时是否稳定(不要用 index,推荐用唯一 id)- 容器本身有没有设置了固定高度或最大高度,否则虚拟滚动无法计算可视区域
- 如果是移动端,某些浏览器对 transform 渲染支持差,可能会卡顿
另外,你提到“控制台没报错”,这不能说明没问题。很多性能问题都是静默的,可以打开 Chrome DevTools 的 Performance 面板做帧分析,看看是哪一块在拖慢渲染。
总之,你不是 key 写得不对,而是压根没用对虚拟滚动 😅。改完上面那段代码,再观察 FPS,应该就能明显提升。如果还有卡顿,再查 item 内容复杂度和浏览器渲染机制的问题。