全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-20 7 分钟 ✍️ juanwangdev

组件渲染优化

组件渲染性能直接影响用户体验,Vue 提供了多种优化手段来减少不必要的渲染开销。

v-show 与 v-if 的选择

JavaScript
// v-if: 真正的条件渲染,切换时销毁/重建
<div v-if="isVisible">内容</div>

// v-show: 始终渲染,仅切换 CSS display
<div v-show="isVisible">内容</div>
场景选择原因
频繁切换v-show避免重复创建销毁
很少切换v-if初始渲染开销更小
条件复杂v-if支持 else/else-if

computed 缓存机制

JavaScript
// computed 有缓存,依赖不变不重新计算
const filteredList = computed(() => {
  return list.value.filter(item => item.active)
})

// methods 每次调用都会执行
const getFilteredList = () => {
  return list.value.filter(item => item.active)
}

优先使用 computed 替代 methods 进行数据计算,避免重复执行。

组件拆分与懒加载

拆分大组件

JavaScript
// 将列表项拆分为独立组件
const ListItem = {
  props: ['item'],
  template: '<div>{{ item.name }}</div>'
}

// 父组件
const List = {
  components: { ListItem },
  template: '<list-item v-for="item in items" :key="item.id" :item="item" />'
}

每个 ListItem 独立维护自己的响应式依赖,减少父组件的更新范围。

异步组件

JavaScript
// Vue 2
const AsyncComp = () => import('./HeavyComponent.vue')

// Vue 3
const AsyncComp = defineAsyncComponent(() =>
  import('./HeavyComponent.vue')
)

减少响应式数据

JavaScript
import { ref, shallowRef, shallowReactive } from 'vue'

// 不需要响应式的静态数据
const staticConfig = { theme: 'dark', lang: 'zh' }

// 浅响应式,只跟踪第一层
const state = shallowReactive({
  list: [{ /* 大数据,不需要深层响应 */ }],
  count: 0
})

// ref 的浅版本
const largeData = shallowRef([])

冻结大对象

JavaScript
// Vue 2: Object.freeze 阻止响应式转换
const largeList = Object.freeze([
  { id: 1, name: 'Item 1' },
  // ... 1000+ items
])

// Vue 3: markRaw 标记非响应式
import { markRaw } from 'vue'
const rawObj = markRaw({ large: 'data' })

虚拟列表

对于超长列表,使用虚拟滚动只渲染可见区域:

JavaScript
const VirtualList = {
  props: ['items', 'itemHeight'],
  computed: {
    visibleItems() {
      const start = Math.floor(this.scrollTop / this.itemHeight)
      const end = start + Math.ceil(this.containerHeight / this.itemHeight)
      return this.items.slice(start, end + 5)
    }
  }
}

防抖与节流

JavaScript
// 防抖:搜索输入
const searchQuery = ref('')
const searchResults = ref([])
let timer = null

watch(searchQuery, (val) => {
  clearTimeout(timer)
  timer = setTimeout(() => {
    searchResults.value = fetchData(val)
  }, 300)
})

要点总结

  • 频繁切换用 v-show,很少切换用 v-if
  • 优先使用 computed 利用缓存特性
  • 大组件拆分为小组件,减少单次更新范围
  • 使用 shallowRef/markRaw 减少不必要的响应式开销
  • 超长列表使用虚拟滚动只渲染可见区域
  • 搜索等高频操作使用防抖/节流

📝 发现内容有误?点击此处直接编辑

← 上一篇 异步更新队列
下一篇 → 虚拟DOM与Diff算法
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库