惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
WordPress大学
WordPress大学
Google DeepMind News
Google DeepMind News
T
The Exploit Database - CXSecurity.com
阮一峰的网络日志
阮一峰的网络日志
F
Fox-IT International blog
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
I
Intezer
P
Privacy & Cybersecurity Law Blog
B
Blog RSS Feed
Latest news
Latest news
小众软件
小众软件
A
Arctic Wolf
Attack and Defense Labs
Attack and Defense Labs
L
LINUX DO - 热门话题
博客园 - 聂微东
B
Blog
T
Troy Hunt's Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
Malwarebytes
Malwarebytes
爱范儿
爱范儿
Recorded Future
Recorded Future
Apple Machine Learning Research
Apple Machine Learning Research
人人都是产品经理
人人都是产品经理
D
Docker
T
Threat Research - Cisco Blogs
MyScale Blog
MyScale Blog
Martin Fowler
Martin Fowler
E
Exploit-DB.com RSS Feed
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
PCI Perspectives
PCI Perspectives
Scott Helme
Scott Helme
N
Netflix TechBlog - Medium
博客园 - 三生石上(FineUI控件)
T
True Tiger Recordings
C
Check Point Blog
Microsoft Azure Blog
Microsoft Azure Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
K
Kaspersky official blog
Security Latest
Security Latest
The Hacker News
The Hacker News
Microsoft Security Blog
Microsoft Security Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Stack Overflow Blog
Stack Overflow Blog
S
Security @ Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
M
Microsoft Research Blog - Microsoft Research

掘金

从“连接不上”到“交易成功”:我用 @solana/web3.js 在 React 中搞定 Solana 钱包交互的全过程 juejin.cn 海量人群包存储优化:基于 RoaringBitmap 交换格式与 Redis 分片 Bitmap 的实践 juejin.cn juejin.cn 鸿蒙项目首页启动链路与 ArkUI 架构学习总结 如何手写一个 AI Agent 工具调用循环(Tool Loop) Tauri 应用首次上架 App Store 被驳回了 3 次(iOS)和 12 轮(macOS)的经历 juejin.cn Flutter 桌面小组件开发 现代多模态大模型的核心基础:Unified Self-Attention juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn Transformer 原论文怎么训出来的:8 张 P100、12 小时、warmup 4000 步 Hermes 升级后,我的 Telegram 附件突然发不出来了 Transformer 中的前馈网络:那个看似平平无奇的两层 MLP,其实是「记忆」所在 AI Coding开始进入第四个时代,我还没上车呢! 【Agentic RL / 强化学习 / OPD】OpenClaw-RL 源码阅读笔记 --- (1)---基础 juejin.cn Vibe Coding 全栈实战:章鱼哥解题 01|搭好产品底座与登录链路 juejin.cn 我让 AI 加了一个开关,结果代码走了原本不该走的分支 Manim物理模拟:别自己写欧拉了! 我也该升级了,陪伴了我7年的博客 juejin.cn juejin.cn MCP 高德地图实战:当 AI 学会使用工具,一个协议如何重塑大模型的行动边界 用魔法打败魔法:我让AI替我去面试前端岗,AI面试官给我打了92分,还发了offer juejin.cn juejin.cn juejin.cn juejin.cn Android Input Spy Window Claude Code CLI 命令大全:60 个原生命令一次讲清 juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn 关于一个新手小白靠claude帮助下的全栈留言板项目开发 juejin.cn juejin.cn juejin.cn 从本地开发到生产部署:用 Docker Compose 跑通 NestJS、MySQL 与 Milvus AI应用开发七:可以替代 RAG 的技术 juejin.cn 小书匠:一款本地优先、去中心化的全能笔记软件 juejin.cn juejin.cn juejin.cn Shadow实战接入与生产落地:从零搭建到稳定运行 Shadow Transform:编译期的魔法——字节码替换实战 juejin.cn juejin.cn Hermes Agent:一个真正“会成长”的开源 AI Agent,正在改变 AI 自动化玩法 juejin.cn juejin.cn juejin.cn 残差连接:为什么深层网络必须留一条直路 juejin.cn FastAPI 从入门到实战:3 分钟构建高性能异步 API juejin.cn juejin.cn CryptoJS:数据安全的JavaScript加密利器 juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn ArkClaw AI 盯盘管家 —— 从手动口令到自动推送,4 套预置定时任务模版一键启用 juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn juejin.cn “杀!杀!杀!”、“我最讨厌事后道歉”——骂“杀哥”之前,谁还没当过情绪崩溃的人
Vue 性能优化实战指南
Csvn · 2026-05-15 · via 掘金

引言

随着 Vue 应用的规模不断扩大,性能问题逐渐显现:长列表渲染卡顿、首屏加载缓慢、组件重复渲染... 本文将深入探讨 Vue 性能优化的两大核心策略:虚拟列表异步组件,帮助你打造流畅的用户体验。

一、虚拟列表:解决长列表渲染瓶颈

问题场景

当列表包含数千条数据时,直接渲染所有 DOM 节点会导致:

  • 页面滚动卡顿
  • 内存占用过高
  • 首次渲染时间过长

解决方案

虚拟列表的核心思想:只渲染可视区域内的元素

实现原理

虚拟列表通过计算可视区域,只渲染用户可见的列表项,大大减少 DOM 节点数量。

代码示例

<template>
  <div class="virtual-list" ref="listContainer">
    <div 
      class="placeholder" 
      :style="{ height: totalHeight + 'px' }"
    >
      <div
        v-for="item in visibleItems"
        :key="item.id"
        class="list-item"
        :style="{ 
          position: 'absolute',
          top: item.offset + 'px'
        }"
      >
        {{ item.content }}
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'

const props = defineProps({
  data: { type: Array, required: true },
  itemHeight: { type: Number, default: 50 },
  bufferSize: { type: Number, default: 5 }
})

const listContainer = ref(null)
const scrollTop = ref(0)

// 计算可视区域
const visibleItems = computed(() => {
  if (!listContainer.value) return []
  
  const containerHeight = listContainer.value.clientHeight
  const startIndex = Math.floor(scrollTop.value / props.itemHeight)
  const visibleCount = Math.ceil(containerHeight / props.itemHeight)
  
  const start = Math.max(0, startIndex - props.bufferSize)
  const end = Math.min(props.data.length, start + visibleCount + props.bufferSize * 2)
  
  return props.data.slice(start, end).map((item, index) => ({
    ...item,
    offset: (start + index) * props.itemHeight
  }))
})

const totalHeight = computed(() => 
  props.data.length * props.itemHeight
)

const handleScroll = (e) => {
  scrollTop.value = e.target.scrollTop
}

onMounted(() => {
  listContainer.value?.addEventListener('scroll', handleScroll)
})

onUnmounted(() => {
  listContainer.value?.removeEventListener('scroll', handleScroll)
})
</script>

<style scoped>
.virtual-list {
  height: 600px;
  overflow-y: auto;
  position: relative;
}

.placeholder {
  position: relative;
}

.list-item {
  height: 50px;
  padding: 10px;
  border-bottom: 1px solid #eee;
}
</style>

使用现成库

推荐使用成熟的虚拟列表库:

npm install vue-virtual-scroller
<template>
  <RecycleScroller
    :items="largeList"
    :item-size="50"
    key-field="id"
  >
    <template #default="{ item }">
      <div class="item">{{ item.name }}</div>
    </template>
  </RecycleScroller>
</template>

二、异步组件:优化首屏加载

问题场景

大型应用中,所有组件打包在一个 bundle 中,导致:

  • 首屏加载时间过长
  • 资源浪费(用户可能不会访问某些页面)

解决方案

代码分割 + 懒加载,只加载当前需要的组件。

基础用法

// 传统方式 - 同步导入
import HeavyComponent from './HeavyComponent.vue'

// 优化方式 - 异步导入
const HeavyComponent = defineAsyncComponent(() => 
  import('./HeavyComponent.vue')
)

带加载状态的异步组件

<script setup>
import { defineAsyncComponent } from 'vue'

// 带 loading 和 error 状态的异步组件
const AsyncComponent = defineAsyncComponent({
  loader: () => import('./HeavyComponent.vue'),
  loadingComponent: LoadingSpinner,
  errorComponent: ErrorFallback,
  delay: 200, // 200ms 后显示 loading
  timeout: 3000 // 3 秒超时
})
</script>

<template>
  <AsyncComponent />
</template>

路由级别的代码分割

// router/index.js
const routes = [
  {
    path: '/',
    component: () => import('@/views/Home.vue')
  },
  {
    path: '/admin',
    component: () => import('@/views/Admin.vue'),
    meta: { requiresAuth: true }
  },
  {
    path: '/settings',
    component: () => import('@/views/Settings.vue')
  }
]

按需加载大型依赖

// 不推荐 - 导入整个库
import lodash from 'lodash'

// 推荐 - 按需导入
import debounce from 'lodash/debounce'
import throttle from 'lodash/throttle'

// 或使用 ES Module 语法
import { debounce, throttle } from 'lodash-es'

三、其他性能优化技巧

1. 使用 v-memo 缓存组件

Vue 3.2+ 引入的 v-memo 可以缓存组件渲染:

<template>
  <div v-memo="[valueA, valueB]">
    {{ valueA }} + {{ valueB }}
  </div>
</template>

2. 避免不必要的响应式

// 对于不需要响应式的大对象,使用 shallowRef
import { shallowRef } from 'vue'

const largeData = shallowRef(null)

// 只在需要时触发更新
const loadData = async () => {
  largeData.value = await fetchLargeData()
}

3. 列表使用 key 优化

<!-- 不推荐 -->
<li v-for="(item, index) in list" :key="index">
  {{ item.name }}
</li>

<!-- 推荐 -->
<li v-for="item in list" :key="item.id">
  {{ item.name }}
</li>

四、性能监控

使用 Vue DevTools 和性能工具:

// 性能监控
const start = performance.now()
// ... 执行操作
const end = performance.now()
console.log(`耗时:${end - start}ms`)

// 或使用 Vue 的 performance API
if (__VUE_PROD__) {
  performance.mark('component-mount-start')
  // ...
  performance.mark('component-mount-end')
  performance.measure('component-mount', 
    'component-mount-start', 
    'component-mount-end'
  )
}

总结

Vue 性能优化的核心原则:

  1. 减少渲染量 - 虚拟列表、分页加载
  2. 延迟加载 - 异步组件、路由懒加载
  3. 避免重复计算 - v-memo、computed 缓存
  4. 按需引入 - 减少 bundle 体积

记住:过早优化是万恶之源。先确保功能正确,再根据实际性能数据进行优化。