技术文档中心
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
  • Vue2 基础

    • Vue 学习指南
    • Vue2 快速入门
    • Vue2 模板语法
    • Vue2 组件基础
    • Vue2 计算属性与侦听器
    • Vue2 生命周期
  • Vue2 进阶

    • Vue2 组件通信
    • Vue2 插槽详解
    • Vue2 混入与自定义指令
    • Vue2 过渡与动画
    • Vuex 状态管理
  • Vue2 高级

    • Vue2 性能优化
    • Vue2 服务端渲染(SSR)
    • Vue2 源码解析
  • Vue3 基础

    • Vue3 快速入门
    • Vue3 Composition API
    • Vue3 响应式系统
    • Vue3 组件基础
    • Vue3 生命周期
  • Vue3 进阶

    • Vue3 组合式函数
    • Vue3 组件通信
    • Vue3 Teleport 与 Suspense
    • Pinia 状态管理
    • Vue Router 4
  • Vue3 高级

    • Vue3 TypeScript
    • Vue3 性能优化
    • Vue3 测试
    • Vue3 SSR
    • Vue3 源码解析
  • 实战项目

    • Vue2 实战项目
    • Vue3 实战项目
    • Vue2 迁移 Vue3

Vue2 性能优化

代码层面优化

v-if vs v-show

<!-- 频繁切换使用 v-show -->
<div v-show="isVisible">Content</div>

<!-- 条件很少改变使用 v-if -->
<div v-if="isLoggedIn">User Panel</div>

计算属性缓存

// 好 - 使用计算属性
computed: {
  filteredList() {
    return this.list.filter(item => item.active)
  }
}

// 差 - 使用方法
methods: {
  filteredList() {
    return this.list.filter(item => item.active)
  }
}

v-for 使用 key

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

避免 v-if 和 v-for 一起使用

<!-- 差 -->
<li v-for="user in users" v-if="user.isActive" :key="user.id">
  {{ user.name }}
</li>

<!-- 好 -->
<li v-for="user in activeUsers" :key="user.id">
  {{ user.name }}
</li>
computed: {
  activeUsers() {
    return this.users.filter(user => user.isActive)
  }
}

事件销毁

created() {
  this.timer = setInterval(() => {}, 1000)
  window.addEventListener('resize', this.handleResize)
},
beforeDestroy() {
  clearInterval(this.timer)
  window.removeEventListener('resize', this.handleResize)
}

图片懒加载

// 使用 vue-lazyload
Vue.use(VueLazyload, {
  preLoad: 1.3,
  loading: 'loading.gif',
  error: 'error.gif'
})
<img v-lazy="imageUrl" />

路由懒加载

const Foo = () => import('./Foo.vue')

const router = new VueRouter({
  routes: [
    { path: '/foo', component: Foo }
  ]
})

第三方插件按需引入

// 差 - 全部引入
import ElementUI from 'element-ui'
Vue.use(ElementUI)

// 好 - 按需引入
import { Button, Select } from 'element-ui'
Vue.component(Button.name, Button)
Vue.component(Select.name, Select)

打包优化

代码分割

// vue.config.js
module.exports = {
  configureWebpack: {
    optimization: {
      splitChunks: {
        chunks: 'all',
        cacheGroups: {
          libs: {
            name: 'chunk-libs',
            test: /[\\/]node_modules[\\/]/,
            priority: 10,
            chunks: 'initial'
          },
          elementUI: {
            name: 'chunk-elementUI',
            priority: 20,
            test: /[\\/]node_modules[\\/]_?element-ui(.*)/
          }
        }
      }
    }
  }
}

压缩代码

// vue.config.js
const TerserPlugin = require('terser-webpack-plugin')

module.exports = {
  configureWebpack: {
    optimization: {
      minimizer: [
        new TerserPlugin({
          terserOptions: {
            compress: {
              drop_console: true
            }
          }
        })
      ]
    }
  }
}

CDN 加速

// vue.config.js
module.exports = {
  configureWebpack: {
    externals: {
      vue: 'Vue',
      'vue-router': 'VueRouter',
      vuex: 'Vuex',
      axios: 'axios'
    }
  }
}
<!-- index.html -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>

运行时优化

Object.freeze

data() {
  return {
    // 冻结大型数据,避免响应式转换
    largeList: Object.freeze([...])
  }
}

函数式组件

export default {
  functional: true,
  props: ['item'],
  render(h, context) {
    return h('div', context.props.item.name)
  }
}

keep-alive

<keep-alive :include="['ComponentA', 'ComponentB']">
  <router-view></router-view>
</keep-alive>

虚拟滚动

<virtual-list
  :size="40"
  :remain="8"
  :bench="10"
>
  <item
    v-for="item in items"
    :key="item.id"
    :item="item"
  />
</virtual-list>
最近更新: 2026/1/27 15:51
Contributors: hailong
Next
Vue2 服务端渲染(SSR)