news 2026/4/23 16:45:36

Vue 长列表卡顿、滚动掉帧怎么办?一次性讲清楚

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue 长列表卡顿、滚动掉帧怎么办?一次性讲清楚

文章目录

    • 前言
    • Vue 长列表为什么一定会卡?
      • 1. v-for 渲染大量节点的真实代价
      • 2. DOM 数量过多,回流重绘是致命的
      • 3. 图文混排 + 复杂组件 = 雪上加霜
    • 核心解法:虚拟列表(Virtual List)
      • 1. 虚拟列表原理一句话版
      • 2. vue-virtual-scroller 快速上手 Demo
        • 安装
        • 基础示例(可直接跑)
        • 关键点解析
    • key 用不好,虚拟列表也救不了你
      • 错误示例
      • 正确示例
    • keep-alive 和组件卸载策略
      • keep-alive 的正确用法
      • 离开页面主动清理数据
    • IntersectionObserver 做懒加载
      • 图片懒加载示例
    • 实战结果:10 万级表格渲染
    • 总结

前言

在 Vue 项目里,只要一遇到长列表,很多同学第一反应都是:

“我这也没干啥啊,就是 v-for 渲染个列表,怎么就卡成 PPT 了?”

更狠一点的,产品一句话:

“这个页面数据有点多,可能十几万条吧。”

然后你就知道,这一页不优化是肯定过不去了。

这篇文章我们就从为什么卡开始,一步一步讲清楚Vue 长列表性能问题的本质,以及真正能落地的解决方案

Vue 长列表为什么一定会卡?

先说结论一句话版:

卡,不是 Vue 慢,是 DOM 太多。

1. v-for 渲染大量节点的真实代价

假设你写了这样一段代码:

<div v-for="item in list" :key="item.id"> {{ item.name }} </div>

如果list有 10 万条数据,意味着什么?

  • 浏览器里会真实创建10 万个 DOM 节点

  • 每次滚动都会涉及:

    • 布局计算(Layout)
    • 回流(Reflow)
    • 重绘(Repaint)
  • 任意一次父组件更新,都可能触发这些节点的 diff

这不是 Vue 的锅,这是浏览器物理极限的问题

2. DOM 数量过多,回流重绘是致命的

浏览器渲染流水线大概是:

JS → Style → Layout → Paint → Composite

当 DOM 数量过多时:

  • Layout 时间暴涨
  • Scroll 时频繁触发 repaint
  • FPS 掉到 30 以下,人眼就明显感觉卡

这也是为什么你会看到:

  • 滚动时页面发虚
  • 快速滑动直接“锁死”
  • 真机比模拟器还卡

3. 图文混排 + 复杂组件 = 雪上加霜

如果列表项里还有:

  • 图片
  • 自定义组件
  • 动态高度
  • hover / 动画

那每一行的渲染成本都会进一步放大。

所以,结论很清楚:

长列表,绝对不能一次性渲染完。

核心解法:虚拟列表(Virtual List)

虚拟列表的核心思想其实很简单:

只渲染“屏幕可见的那一小部分 DOM”,其他的用占位撑高度。

1. 虚拟列表原理一句话版

假设屏幕一次最多只能看到 20 行:

  • DOM 中永远只存在 20~30 行
  • 滚动时,复用 DOM 节点
  • 数据在变,DOM 不新增

这就是虚拟列表。


2. vue-virtual-scroller 快速上手 Demo

这是 Vue 里最成熟、最常用的方案之一。

安装
npminstallvue-virtual-scroller
基础示例(可直接跑)
<template> <RecycleScroller :items="list" :item-size="50" key-field="id" > <template #default="{ item }"> <div class="row"> {{ item.text }} </div> </template> </RecycleScroller> </template> <script setup> import { RecycleScroller } from 'vue-virtual-scroller' const list = Array.from({ length: 100000 }).map((_, i) => ({ id: i, text: `第 ${i} 行数据` })) </script>
关键点解析
  • item-size非常重要,最好是固定高度
  • key-field:告诉组件用哪个字段复用 DOM
  • 内部使用的是 DOM 复用,不是频繁创建/销毁

实测:10 万条数据,滚动依然 60 FPS。

key 用不好,虚拟列表也救不了你

很多列表性能问题,其实是key 用错了

错误示例

<div v-for="(item, index) in list" :key="index">

问题:

  • 数据插入 / 删除时
  • index 全部变化
  • Vue 会误以为所有节点都变了

正确示例

<div v-for="item in list" :key="item.id">

记住一句话:

key 一定要稳定、唯一、和业务语义一致。

keep-alive 和组件卸载策略

在分页列表或 Tab 场景中,经常会遇到:

“切换回来列表还在,但怎么感觉越来越卡?”

keep-alive 的正确用法

<keep-alive :max="2"> <router-view /> </keep-alive>
  • 控制缓存页面数量
  • 避免无限缓存导致内存膨胀

离开页面主动清理数据

onDeactivated(()=>{list.value=[]})

对于超大列表,离开页面就应该释放内存,不要心疼。

IntersectionObserver 做懒加载

对于图片、复杂组件,可以再加一层优化。

图片懒加载示例

constobserver=newIntersectionObserver(entries=>{entries.forEach(entry=>{if(entry.isIntersecting){entry.target.src=entry.target.dataset.src observer.unobserve(entry.target)}})})
  • 图片进入可视区才加载
  • 极大降低首屏压力

实战结果:10 万级表格渲染

优化前:

  • 首屏白屏 3~5 秒
  • 滚动 FPS < 30

优化后(虚拟列表 + 懒加载):

  • 首屏 < 500ms
  • 滚动稳定 60 FPS

总结

Vue 长列表优化,本质是“控制 DOM 数量”。
只要 DOM 在可控范围内,性能问题基本都能解决。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 13:55:28

PiliPlus终极体验指南:解锁B站第三方客户端的完整功能指南

PiliPlus终极体验指南&#xff1a;解锁B站第三方客户端的完整功能指南 【免费下载链接】PiliPlus PiliPlus 项目地址: https://gitcode.com/gh_mirrors/pi/PiliPlus 想要在B站获得超越官方的个性化体验&#xff1f;PiliPlus作为基于Flutter开发的第三方B站客户端&#x…

作者头像 李华
网站建设 2026/4/17 16:44:12

FlexboxLayout布局革命:掌握WrapBefore精准换行控制

还记得那些被LinearLayout和RelativeLayout束缚的日子吗&#xff1f;当你的布局需求稍微复杂一点&#xff0c;就需要嵌套多层布局&#xff0c;代码变得臃肿不堪。现在&#xff0c;FlexboxLayout为你带来了布局设计的全新可能&#xff0c;特别是其独特的layout_wrapBefore属性&a…

作者头像 李华
网站建设 2026/4/23 13:55:29

报错分析:注册通知例程达上限

如图所示&#xff0c;代码中 if (NT_SUCCESS(Status))的判断失败了&#xff0c;进入了 else 分支。正如else分支中的注释所说&#xff1a; // too many notify routines are already installed in the system。说明此时系统中已经安装了太多的通知例程&#xff0c;注册表通知达…

作者头像 李华
网站建设 2026/4/23 10:35:41

如何快速获取阿里云盘Refresh Token:扫码工具完整使用指南

还在为阿里云盘API授权而烦恼吗&#xff1f;想象一下&#xff0c;你正在开发一个云盘管理工具&#xff0c;却卡在了获取Refresh Token这个关键环节上。传统的授权流程复杂繁琐&#xff0c;让人望而却步。今天&#xff0c;我将为你介绍一款基于二维码扫描的阿里云盘Refresh Toke…

作者头像 李华
网站建设 2026/4/23 13:55:25

5步精通Maccy剪贴板管理:从新手到效率达人的完整教程

5步精通Maccy剪贴板管理&#xff1a;从新手到效率达人的完整教程 【免费下载链接】Maccy Lightweight clipboard manager for macOS 项目地址: https://gitcode.com/gh_mirrors/ma/Maccy 在数字化工作环境中&#xff0c;剪贴板管理工具已成为提升效率的必备利器。Maccy作…

作者头像 李华
网站建设 2026/4/23 15:33:46

3分钟搞定动态圣诞树:零基础也能玩的编程魔法

你是否想过&#xff0c;用几行代码就能创造出令人惊艳的3D动画效果&#xff1f;螺旋圣诞树项目正是这样一个将数学美学与编程魔法完美融合的典范。这个基于Reddit灵感开发的项目&#xff0c;仅用极简的代码就构建出了动态旋转的3D圣诞树视觉效果。 【免费下载链接】atree Just …

作者头像 李华