理解vue-cli 中进行构建优化

发布于:2025-05-28 ⋅ 阅读:(86) ⋅ 点赞:(0)

在 Vue CLI 项目中进行构建优化,是前端性能提升的重要手段。它涉及到 Webpack 配置、代码分包、懒加载、依赖优化、图片压缩等多个方面。

🧱 基础构建优化

设置生产环境变量

NODE_ENV=production

Vue CLI 会自动在 npm run build 时开启以下优化:

  • 压缩 JS / CSS
  • 移除 console 和 debugger
  • 自动分离 vendor 文件(依赖包)

开启 gzip 压缩

使用 compression-webpack-plugin:

npm install compression-webpack-plugin -D
// vue.config.js
const CompressionWebpackPlugin = require('compression-webpack-plugin')

module.exports = {
  configureWebpack: {
    plugins: [
      new CompressionWebpackPlugin({
        algorithm: 'gzip',
        test: /\.(js|css|html|svg)$/,
        threshold: 10240,
        minRatio: 0.8
      })
    ]
  }
}

去除 map 文件

module.exports = {
  productionSourceMap: false
}

📦 代码层优化

路由懒加载(代码分割)

const Home = () => import(‘@/views/Home.vue’)

打包时,每个路由页面都会单独分包。

使用 CDN 加载库文件

把 Vue、Vuex、Vue Router 等用 CDN 引入:

// vue.config.js
module.exports = {
  configureWebpack: {
    externals: {
      vue: 'Vue',
      'vue-router': 'VueRouter',
      vuex: 'Vuex'
    }
  }
}

然后在 public/index.html 中引入 CDN:

<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>

Tree Shaking & 按需引入

避免全量引入组件库,例如:

// ❌ 错误
import ElementPlus from 'element-plus'
app.use(ElementPlus)

// ✅ 推荐
import { ElButton, ElSelect } from 'element-plus'
app.use(ElButton).use(ElSelect)

🧠 Webpack 配置层优化(Vue CLI 内部使用 Webpack)

使用缓存

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.cache(true)
  }
}

分析包体积

npm install webpack-bundle-analyzer -D
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

module.exports = {
  configureWebpack: {
    plugins: [new BundleAnalyzerPlugin()]
  }
}

🖼 资源层优化

图片压缩

使用 image-webpack-loader:

npm install image-webpack-loader -D
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('images')
      .use('image-webpack-loader')
      .loader('image-webpack-loader')
      .options({
        mozjpeg: { progressive: true, quality: 65 },
        pngquant: { quality: [0.65, 0.90], speed: 4 }
      })
  }
}

图片懒加载

npm install vue-lazyload
import VueLazyload from 'vue-lazyload'
app.use(VueLazyload, { loading: 'loading.png' })

🧊 缓存优化(浏览器缓存策略)

文件名加 hash(默认支持)

Vue CLI 打包后文件名默认带有 [hash],有助于浏览器缓存:

app.234d7f.js

静态资源持久缓存(使用 CDN + Cache-Control)

在 nginx 或服务端配置:

Cache-Control: max-age=31536000

✅ 总结表格

优化项 方法 效果
路由懒加载 import() 异步组件 减少初始加载体积
CDN 加载依赖 externals + script 标签 减少 bundle 体积
gzip 压缩 compression-webpack-plugin 减少传输体积
移除 console terser 插件自动处理 减少无用代码
图片压缩 image-webpack-loader 优化图片大小
分析构建 webpack-bundle-analyzer 找出最大依赖
map 文件移除 productionSourceMap: false 避免泄露源代码
资源缓存 hash 文件名 + Cache-Control 浏览器缓存优化

示例

以下是一个Vue CLI 项目中的完整优化配置文件 vue.config.js,包含以下功能:
• 关闭 source map
• 使用 CDN 外部引入 Vue、Vuex、Vue Router
• gzip 压缩
• 图片压缩
• 移除 console/debugger
• 打包分析器(可选)

✅ vue.config.js

const CompressionWebpackPlugin = require('compression-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const isProd = process.env.NODE_ENV === 'production'

module.exports = {
  productionSourceMap: false, // 关闭 source map

  configureWebpack: config => {
    const plugins = []

    // gzip 压缩
    if (isProd) {
      plugins.push(
        new CompressionWebpackPlugin({
          algorithm: 'gzip',
          test: /\.(js|css|html|svg)$/,
          threshold: 10240,
          minRatio: 0.8
        })
      )
    }

    // CDN 依赖(在 index.html 中引入)
    config.externals = isProd
      ? {
          vue: 'Vue',
          'vue-router': 'VueRouter',
          vuex: 'Vuex'
        }
      : {}

    config.plugins = [...config.plugins, ...plugins]
  },

  chainWebpack: config => {
    // 图片压缩
    config.module
      .rule('images')
      .use('image-webpack-loader')
      .loader('image-webpack-loader')
      .options({
        mozjpeg: { progressive: true, quality: 65 },
        optipng: { enabled: false },
        pngquant: { quality: [0.65, 0.9], speed: 4 },
        gifsicle: { interlaced: false },
        webp: { quality: 75 }
      })

    // 打包分析(按需启用)
    if (process.env.ANALYZE) {
      config
        .plugin('webpack-bundle-analyzer')
        .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
    }
  },

  // 移除 console/debugger(可选)
  configureWebpack: config => {
    if (isProd) {
      config.optimization = {
        minimizer: [
          new TerserPlugin({
            terserOptions: {
              compress: {
                drop_console: true,
                drop_debugger: true
              }
            },
            extractComments: false
          })
        ]
      }
    }
  }
}

✅ 还需要在 public/index.html 中引入 CDN(用于生产环境)

<!-- public/index.html -->
<head>
  <title>Vue App</title>
  <% if (process.env.NODE_ENV === 'production') { %>
    <script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vuex@4.1.0/dist/vuex.global.prod.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-router@4.1.0/dist/vue-router.global.prod.js"></script>
  <% } %>
</head>

网站公告

今日签到

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