Vue 3 页面卡顿排查:响应式依赖、长任务与列表渲染
Vue 3 页面卡顿排查响应式依赖、长任务与列表渲染Vue 3 页面卡顿可能来自响应式依赖过宽、主线程长任务或一次渲染太多节点。先量出三者各自占比再选择 shallowRef、Worker 或虚拟列表。1. 掉帧与主线程阻塞排查链路可以使用 Chrome DevTools 的 Performance 和 Performance Monitor 工具对卡顿现场进行录制与诊断# 在 Lighthouse/Puppeteer 中自动化捕获前端运行时的 FPS 与 Long Tasks 报告 npx lighthouse http://localhost:8080/dashboard --only-categoriesperformance --view # 在 Node.js 端利用 puppeteer-core 模拟万级数据量下 UI 主线程耗时 node ./scripts/perf-audit.js排查得出的性能瓶颈定位如下响应式深度监听过载Over-reactive Tracking把 5000 行包含数十个嵌套字段的 Raw Data 原封不动塞进了 Vue3 的ref()或reactive()中。Vue3 会为每一个层级的属性递归创建 Proxy 实例导致内存上升依赖收集耗时拉长。巨量 DOM 节点一次性挂载没有使用虚拟滚动Virtual Scroll一次性创建了数万个 DOM 节点触发布局计算Recalculate Style Layout和重绘。计算密集型任务占据主线程排序、过滤、聚合统计等复杂计算全部跑在 UI 主线程直接卡死 Animation Frame。2. Web Worker 计算下沉与虚拟滚动实现大量数据下可分别评估shallowRef、Web Worker 和虚拟列表。三者解决的问题不同是否采用由响应式开销、计算时间和可见节点数决定。下面的代码示例展示了如何在 Vue3 组件中结合 Worker 与虚拟渲染template div classvirtual-container refcontainerRef scrollhandleScroll !-- 撑开总高度的占位元素 -- div classphantom-space :style{ height: totalHeight px }/div !-- 视口切片渲染区域 -- div classrender-content :style{ transform: translate3d(0, ${offsetY}px, 0) } div v-foritem in visibleData :keyitem.id classdata-row :style{ height: itemHeight px } span classcol-id#{{ item.id }}/span span classcol-name{{ item.title }}/span span classcol-val{{ item.formattedValue }}/span /div /div /div /template script setup langts import { ref, shallowRef, computed, onMounted, onUnmounted } from vue; interface DataItem { id: number; title: string; value: number; formattedValue?: string; } const itemHeight 40; // 单行固定高度 const containerRef refHTMLElement | null(null); const scrollTop ref(0); const totalCount ref(0); // 使用 shallowRef 避免深度代理极大降低内存与依赖收集开销 const rawDataset shallowRefDataItem[]([]); const filteredIndices shallowRefnumber[]([]); let worker: Worker | null null; // 1. 初始化 Web Worker 进行后台排序过滤 const initWorker () { const workerCode self.onmessage function(e) { const { list, keyword } e.data; // 在 Worker 线程进行耗时筛选计算 const matched []; for(let i 0; i list.length; i) { if(list[i].title.includes(keyword)) { matched.push(i); } } self.postMessage({ matchedIndices: matched }); }; ; const blob new Blob([workerCode], { type: application/javascript }); worker new Worker(URL.createObjectURL(blob)); worker.onmessage (e) { filteredIndices.value e.data.matchedIndices; totalCount.value e.data.matchedIndices.length; }; }; // 2. 虚拟列表切片计算 const totalHeight computed(() totalCount.value * itemHeight); const visibleCount ref(15); const startIndex computed(() Math.floor(scrollTop.value / itemHeight)); const endIndex computed(() Math.min(startIndex.value visibleCount.value 5, totalCount.value)); const offsetY computed(() startIndex.value * itemHeight); const visibleData computed(() { const indices filteredIndices.value.slice(startIndex.value, endIndex.value); return indices.map(idx rawDataset.value[idx]); }); const handleScroll (e: Event) { const target e.target as HTMLElement; scrollTop.value target.scrollTop; }; // 模拟加载大批量数据 onMounted(() { initWorker(); const mockData: DataItem[] Array.from({ length: 20000 }, (_, i) ({ id: i 1, title: 指标明细数据试例_${i 1}, value: Math.random() * 1000, formattedValue: $${(Math.random() * 1000).toFixed(2)} })); rawDataset.value mockData; // 触发 Worker 筛选 worker?.postMessage({ list: mockData, keyword: 数据试例 }); if (containerRef.value) { visibleCount.value Math.ceil(containerRef.value.clientHeight / itemHeight); } }); onUnmounted(() { worker?.terminate(); }); /script style scoped .virtual-container { height: 500px; overflow-y: auto; position: relative; border: 1px solid #e2e8f0; } .phantom-space { position: absolute; left: 0; top: 0; right: 0; z-index: -1; } .render-content { position: absolute; left: 0; right: 0; top: 0; } .data-row { display: flex; align-items: center; padding: 0 16px; border-bottom: 1px solid #f1f5f9; box-sizing: border-box; } .col-id { width: 80px; color: #64748b; } .col-name { flex: 1; color: #0f172a; } .col-val { width: 120px; font-weight: 600; text-align: right; } /style3. 调优前后对比数据优化完成后可以在不同数据规模下再次录制了 Performance 面板指标# 监测浏览器渲染线程的 FPS 与 Memory 状态 # 使用 Chrome 开发者工具中的 Performance Monitor 面板实时观测使用同一数据集和设备记录优化前后指标并保存原始录制文件性能指标优化前 (全量响应式 渲染全部 DOM)优化后 (shallowRef Worker 虚拟滚动)目标数据集首次渲染时间优化前基线 (全量响应式 渲染全部 DOM)优化后结果 (shallowRef Worker 虚拟滚动)内存占用 (JS Heap)优化前基线 (全量响应式 渲染全部 DOM)优化后结果 (shallowRef Worker 虚拟滚动)快速滚动平均 FPS优化前基线 (全量响应式 渲染全部 DOM)优化后结果 (shallowRef Worker 虚拟滚动)长任务 (Long Task) 数量优化前基线 (全量响应式 渲染全部 DOM)优化后结果 (shallowRef Worker 虚拟滚动)4. 经验总结前端性能优化不是靠凭空想象而是看数据和排障证据。在应对复杂视图和海量数据时记住这三个原则不用无脑嵌套reactive()对于大量只读或仅供展示的数据优先考虑shallowRef()或markRaw()切断不必要的深度代理。让主线程专注做渲染先用 Performance 录制确认 Array 计算、正则过滤或数据转换是否持续占用主线程超过交互帧预算的任务再拆分或下沉到 Web Worker。DOM 节点“按需供给”无论是表格、树形控件还是下拉列表超过 100 条数据就应该默认引入虚拟滚动机制。

相关新闻

SMBus is busy, can‘t use it! + task blocked 120s - i2c-i801 错误路径释放未获取资源致 hung task(CVE-2026-64205)

SMBus is busy, can‘t use it! + task blocked 120s - i2c-i801 错误路径释放未获取资源致 hung task(CVE-2026-64205)

title: “运维漏洞指南:SMBus is busy, can’t use it! 日志洪泛 INFO: task blocked for more than 120 seconds——i2c-i801 驱动错误路径释放未获取资源导致 hung task panic(CVE-2026-64205 内核源码级解析)” column: “运维漏洞指南”…

2026/10/20 2:35:54 阅读更多 →
iTunes恢复按钮变灰?Windows权限与备份文件修复全攻略

iTunes恢复按钮变灰?Windows权限与备份文件修复全攻略

1. 问题引入:当“恢复”按钮不再响应 如果你也遇到过在Windows电脑上用iTunes备份了iPhone或iPad数据,等到需要恢复时,却发现那个至关重要的“恢复”按钮是灰色的,无法点击,那你肯定能体会那种瞬间的焦虑和无助。数据备…

2026/10/20 6:09:48 阅读更多 →
高并发场景下“高通常见nv”报错深度剖析与实战解决方案

高并发场景下“高通常见nv”报错深度剖析与实战解决方案

1. 项目缘起:一个“高通常见”的误解 最近在排查一个线上服务的性能问题时,又遇到了那个熟悉又让人头疼的报错:“高通常见nv”。这个报错信息,乍一看有点不知所云,但如果你在分布式系统、微服务或者高并发场景下工作过…

2026/10/19 12:03:03 阅读更多 →

最新新闻

MATLAB小波分析实战手册:EEG/ECG/振动信号降噪与特征提取

MATLAB小波分析实战手册:EEG/ECG/振动信号降噪与特征提取

简介:本资源是《MATLAB小波分析超级学习手册》配套的完整程序代码包,面向信号处理、图像分析及科研工程领域的MATLAB初学者与进阶用户,聚焦小波理论落地与工程实践能力提升。压缩包含119个文件(113个.m函数脚本、4个.wav测试音频、…

2026/10/20 12:23:13 阅读更多 →
华为交换机LACP链路聚合配置实战:负载分担与故障排查

华为交换机LACP链路聚合配置实战:负载分担与故障排查

1. 从一个真实故障说起:为什么单根网线永远不够用很多刚入行的网络运维同行都有过这样的经历:机房搬迁,核心交换机到接入交换机的链路只有一根千兆网线,业务高峰期一到,监控大屏上那条链路的使用率直接顶到95%以上&…

2026/10/20 12:23:13 阅读更多 →
数据预处理全攻略:从数据清洗到缺失值处理,打好数据分析地基

数据预处理全攻略:从数据清洗到缺失值处理,打好数据分析地基

做数据分析这几年,我见过太多人把精力全扑在算法调参上,反复调了好几天,模型效果怎么都上不去,最后排查来排查去才发现,问题根本不在模型,而是喂给模型的数据本身就没洗干净。脏数据、缺失值、量纲悬殊、时…

2026/10/20 12:23:13 阅读更多 →
用 LangGraph 搭建带工具调用的多轮智能体:从状态机设计到流式输出实战

用 LangGraph 搭建带工具调用的多轮智能体:从状态机设计到流式输出实战

引言:能调工具的 Chatbot,离"可用"还有多远 过去一年,几乎每个团队都写过类似这样的代码:把工具 schema 丢给 LLM,拿回 tool_calls,for 循环里逐个执行,把结果拼回消息列表&#xff0…

2026/10/20 12:23:13 阅读更多 →
用 LangChain 和 Ollama 搭建本地 RAG 智能体问答系统

用 LangChain 和 Ollama 搭建本地 RAG 智能体问答系统

引言:本地 RAG 的真实驱动力 过去一年,我参与过几个企业内部知识库项目,几乎每一次技术选型会议都会出现同一个分歧:用云端大模型 API,还是全部本地化部署? 云端方案的优势很明确——模型能力强、开箱即用。…

2026/10/20 12:23:13 阅读更多 →
STM32F4实战:EC20 TCP透传模式与AT指令初始化流程详解

STM32F4实战:EC20 TCP透传模式与AT指令初始化流程详解

简介:针对EC20模块在STM32F4系列微控制器上实现TCP透传通信的场景,这份压缩包提供了一套完整的Keil工程源码,适合物联网开发者、嵌入式工程师以及学习STM32通信技术的读者参考。压缩包内共有174个文件,整体大小约4.06MB&#xff0…

2026/10/20 12:22:13 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →