Skip to content

项目优化

主要从以下几个方面考虑:

  1. 构建层面:使用 Vite 的代码分割、Tree Shaking,配置合理的 chunk 拆分策略,第三方库使用 CDN。
  2. 加载性能层面:路由懒加载、组件异步加载、图片懒加载和压缩。
  3. 运行时性能层面:Vue 3 用 v-memo、shallowRef 优化,大列表用虚拟滚动,避免不必要的响应式。
  4. 网络层面:接口请求防重复、数据缓存、使用防抖节流。
  5. 监控层面:使用 Lighthouse 分析性能,监控首屏加载时间、白屏时间等关键指标。

1. 构建优化

  • visualizer:分析打包体积,找出大体积依赖。
  • 减少打包体积:
    • Tree Shaking:确保代码和依赖库支持 Tree Shaking。
    • 按需引入第三方库(如 Element Plus、Lodash)。
    • sourcemap:某些情况下,生产环境可关闭或者调整 sourcemap 以减少体积。
    • 去除 console 和 debugger。
  • 代码分割:合理拆分 chunk,减少首屏加载体积。
  • compression:生成 gzip 或 brotli 静态资源。
js
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://www.npmjs.com/package/rollup-plugin-visualizer
import { visualizer } from 'rollup-plugin-visualizer'
// https://www.npmjs.com/package/vite-plugin-compression
import compression from 'vite-plugin-compression'

export default defineConfig({
  plugins: [
    vue(),
    // 打包体积分析
    visualizer({
      open: true,
      gzipSize: true,
      brotliSize: true,
    }),
  ],
  build: {
    // 代码分割
    rollupOptions: {
      output: {
        manualChunks: {
          'vue-vendor': ['vue', 'vue-router', 'pinia'],
          'ui-vendor': ['element-plus'], // 或 arco-design-vue
          'utils': ['axios', 'dayjs'],
        },
      },
    },
    // 压缩配置
    minify: 'terser', // 'oxc' | 'terser' | 'esbuild'
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true,
      },
    },
    // chunk 大小警告阈值
    chunkSizeWarningLimit: 1000,
  },
})
js
// vue.config.js
module.exports = {
  productionSourceMap: false,
  configureWebpack: {
    optimization: {
      splitChunks: {
        chunks: 'all',
        cacheGroups: {
          vendor: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendors',
            priority: 10,
          },
          elementUI: {
            test: /[\\/]node_modules[\\/]element-ui[\\/]/,
            name: 'element-ui',
            priority: 20,
          },
        },
      },
    },
  },
}

2. 加载性能优化

  1. 路由懒加载

    js
    // Vue Router 懒加载
    const routes = [
      {
        path: '/dashboard',
        component: () => import(/* webpackChunkName: "dashboard" */ '@/views/Dashboard.vue'),
      },
      {
        path: '/user',
        component: () => import(/* webpackChunkName:  "user" */ '@/views/User.vue'),
      },
    ]
  2. 组件懒加载

    js
    import { defineAsyncComponent } from 'vue'
    
    // 异步组件
    const HeavyComponent = defineAsyncComponent(() => import('./components/HeavyComponent.vue'))
  3. 图片懒加载和压缩

    • 使用 Intersection Observer API 实现图片懒加载。
    • 使用工具(如 ImageOptimTinyPNG)或构建插件(如 vite-plugin-imagemin)压缩图片体积。

3. 运行时性能优化

vue
<script setup>
import { ref, computed, shallowRef, shallowReactive } from 'vue'

// 1. 使用 shallowRef/shallowReactive 处理大型数据
const bigList = shallowRef([])

// 2. 计算属性缓存
const filteredList = computed(() => {
  return bigList.value.filter((item) => item.active)
})

// 3. v-memo 优化列表渲染(Vue 3.2+)
</script>

<template>
  <!-- 使用 v-once -->
  <div v-once>This content will not re-render.</div>

  <!-- 使用 v-memo 缓存不变的部分(超大列表) -->
  <div v-for="item in list" :key="item.id" v-memo="[item.id, item.selected]">
    {{ item.name }}
  </div>

  <!-- 使用 v-show 而非 v-if(频繁切换的元素) -->
  <div v-show="isVisible">Content</div>

  <!-- 虚拟滚动(处理大列表) -->
  <virtual-list :items="bigList" :item-height="50" />
</template>
jsx
import { memo, useMemo, useCallback, lazy, Suspense } from 'react'

// 1. React.memo 避免不必要的重渲染
const ExpensiveComponent = memo(
  ({ data }) => {
    return <div>{data.name}</div>
  },
  (prevProps, nextProps) => {
    return prevProps.data.id === nextProps.data.id
  },
)

// 2. useMemo 缓存计算结果
const memoizedValue = useMemo(() => {
  return expensiveCalculation(data)
}, [data])

// 3. useCallback 缓存函数
const handleClick = useCallback(() => {
  doSomething(param)
}, [param])

// 4. 懒加载组件
const LazyComponent = lazy(() => import('./LazyComponent'))

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  )
}

4. 网络优化

  1. 防重复请求。
  2. 缓存接口数据。例如:用户信息、角色权限等不频繁变化的数据。
  3. CDN 加速静态资源和接口请求。

5. 代码质量优化

  1. Tree Shaking 和按需引入,减少冗余代码。
  2. 防抖、节流,优化高频事件处理。
  3. 代码规范:
    1. 使用 ESLint 规范代码风格,Prettier 格式化代码。
    2. 使用 TypeScript 提升代码健壮性。
    3. 使用 Git Hooks(如 Husky)在提交前进行代码检查和测试,确保代码质量。

基于 MIT 许可发布