Vue 性能优化

发布于:2025-06-16 ⋅ 阅读:(19) ⋅ 点赞:(0)


Vue 性能优化

背景介绍

性能优化是 Vue 应用开发中的重要环节,良好的性能可以提升用户体验。Vue 提供了多种性能优化的方式,包括虚拟 DOM、组件缓存、懒加载等技术。

虚拟 DOM 优化

1. 虚拟 DOM 原理

// 简化的虚拟 DOM 实现
class VNode {
  constructor(tag, props, children) {
    this.tag = tag
    this.props = props
    this.children = children
  }
}

// 创建虚拟 DOM
function h(tag, props, children) {
  return new VNode(tag, props, children)
}

// 渲染虚拟 DOM
function render(vnode, container) {
  const el = document.createElement(vnode.tag)
  for (const key in vnode.props) {
    el.setAttribute(key, vnode.props[key])
  }
  if (typeof vnode.children === 'string') {
    el.textContent = vnode.children
  } else {
    vnode.children.forEach(child => render(child, el))
  }
  container.appendChild(el)
}

2. Diff 算法优化

// 简化的 Diff 算法
function patch(oldVNode, newVNode) {
  // 1. 如果节点类型不同,直接替换
  if (oldVNode.tag !== newVNode.tag) {
    return replaceNode(oldVNode, newVNode)
  }

  // 2. 如果节点类型相同,更新属性
  updateProps(oldVNode, newVNode)

  // 3. 更新子节点
  updateChildren(oldVNode.children, newVNode.children)
}

组件优化

1. 组件缓存

<template>
  <router-view v-slot="{ Component }">
    <keep-alive>
      <component :is="Component" />
    </keep-alive>
  </router-view>
</template>

<script>
export default {
  name: 'CachedComponent',
  // 指定需要缓存的组件
  include: ['Home', 'About'],
  // 指定不需要缓存的组件
  exclude: ['Login'],
}
</script>

2. 异步组件

// 异步组件定义
const AsyncComponent = defineAsyncComponent({
  loader: () => import('./HeavyComponent.vue'),
  loadingComponent: LoadingComponent,
  errorComponent: ErrorComponent,
  delay: 200,
  timeout: 3000,
})

数据优化

1. 计算属性缓存

export default {
  computed: {
    // 使用计算属性缓存结果
    filteredList() {
      return this.items.filter(item => item.active)
    },
  },
}

2. 防抖和节流

import { debounce } from 'lodash-es'

export default {
  methods: {
    // 防抖
    handleSearch: debounce(function () {
      this.search()
    }, 300),

    // 节流
    handleScroll: throttle(function () {
      this.checkScroll()
    }, 200),
  },
}

渲染优化

1. v-show 和 v-if

<template>
  <!-- 频繁切换使用 v-show -->
  <div v-show="isVisible">频繁切换的内容</div>

  <!-- 条件很少改变使用 v-if -->
  <div v-if="isAdmin">管理员内容</div>
</template>

2. 列表渲染优化

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

<script>
export default {
  data() {
    return {
      items: [],
    }
  },
  methods: {
    // 使用 Object.freeze 冻结不需要响应式的数据
    initItems() {
      this.items = Object.freeze([
        { id: 1, name: 'Item 1' },
        { id: 2, name: 'Item 2' },
      ])
    },
  },
}
</script>

打包优化

1. 路由懒加载

const routes = [
  {
    path: '/user',
    component: () => import('./views/User.vue'),
  },
]

2. 组件按需加载

// 按需导入组件
import { Button, Input } from 'element-plus'

常见问题

1. 内存泄漏

export default {
  mounted() {
    // 添加事件监听
    window.addEventListener('resize', this.handleResize)
  },
  beforeUnmount() {
    // 移除事件监听
    window.removeEventListener('resize', this.handleResize)
  },
}

2. 大数据渲染

// 虚拟列表实现
export default {
  data() {
    return {
      items: [],
      visibleCount: 20,
      startIndex: 0,
    }
  },
  computed: {
    visibleItems() {
      return this.items.slice(this.startIndex, this.startIndex + this.visibleCount)
    },
  },
}

面试题

  1. Vue 的性能优化方式有哪些?
// 答案要点:
// 1. 虚拟 DOM 和 Diff 算法优化
// 2. 组件缓存(keep-alive)
// 3. 异步组件和路由懒加载
// 4. 计算属性缓存
// 5. v-show 和 v-if 的合理使用
// 6. 大数据渲染优化
// 7. 打包优化
  1. v-show 和 v-if 的区别?
// 答案要点:
// 1. v-show 只是切换 display
// 2. v-if 会销毁和重建 DOM
// 3. v-show 适合频繁切换
// 4. v-if 适合条件很少改变
  1. 如何优化大数据列表渲染?
// 答案要点:
// 1. 使用虚拟列表
// 2. 分页加载
// 3. 使用 Object.freeze
// 4. 使用 v-show 代替 v-if
// 5. 使用计算属性缓存

网站公告

今日签到

点亮在社区的每一天
去签到