美文网首页Vue.jsvue
vue-cli3 打包优化

vue-cli3 打包优化

作者: zhudying | 来源:发表于2020-07-13 15:08 被阅读0次

    本文具体介绍 vue.config.js 配置,以优化打包后 chunk-vendors.js 的大小,不具体介绍代码优化及各类api封装等。

    1. 老生常谈的代码层面的优化
    1. 按需引入各类组件库
      详情请见element 官网
      1)element,echarts等
      // element
      import { Button, Input } from 'element-ui';
      Vue.use(Button).use(Input);
      
      // echarts
      //引入基本模板
      let echarts = require('echarts/lib/echarts')
    
      // 引入折线图等组件
      require('echarts/lib/chart/gauge')
      require('echarts/lib/chart/radar')
      Vue.prototype.$echarts = echarts
    

    .babel.config.js

    module.exports = {
      presets: [["@vue/app", { useBuiltIns: "entry" }]],
      plugins: [
        // element官方教程
        [
          "component",
          {
            libraryName: "element-ui",
            styleLibraryName: "theme-chalk"
          }
        ]
      ]
    }
    
    1. v-if 和 v-show选择调用
      1)少使用v-if
      2)绑定key

    2. 细分vuejs组件
      1)组件细分,比如一个组件,可以把整个组件细分成轮播组件、列表组件、分页组件等。

    3. 减少watch的数据
      1)数据大时,系统会出现卡顿,所以减少watch的数据。

    4. 路由懒加载
      1)分割路由,当路由被访问的时候才加载对应的组件。

      const router = new VueRouter({
        routes: [
          { path: '/foo', component:  () => import('./Foo.vue')}
        ]
      })
    
    1. 内容类系统的图片资源按需加载
      1)图片加载比较多,使用v-lazy之类的懒加载。
      npm install vue-lazyload --save-dev
      import VueLazyload from 'vue-lazyload'
      Vue.use(VueLazyload)
    
      <img v-lazy="/static/img/1.png">
    
    1. 手动清除各类事件监听器,定时器及闭包等

    2. SSR(服务端渲染)
      如果项目比较大,首屏无论怎么做优化,都出现闪屏或者一阵黑屏的情况。可以考虑使用SSR(服务端渲染)

    2. webpack 打包的优化

    查看各类占比 npm run build --report
    在 dist 文件里,report.html 在浏览器打开即可

    1. 开启gzip压缩
    // 下载
    npm install compression-webpack-plugin --save-dev
    
    const isProduction = ["production", "prod"].includes(process.env.NODE_ENV);
    const CompressionWebpackPlugin = require('compression-webpack-plugin');
    const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;
    
    configureWebpack: config => {
        const plugins = [];
        if (isProduction) {
           plugins.push(
                  new CompressionWebpackPlugin({
                  filename: "[path].gz[query]",
                  algorithm: "gzip",
                  test: productionGzipExtensions,
                  threshold: 10240,
                  minRatio: 0.8
               })
           );
        }
      config.plugins = [...config.plugins, ...plugins];
    }
    
    1. splitChunks 单独打包第三方模块
      // webpack配置
      chainWebpack: (config) => {
        if (isProduction) {
          config.optimization.delete("splitChunks");
        }
        return config;
      },
    
      configureWebpack: config => {
        if (isProduction) {
          // 利用 splitChunks 单独打包第三方模块
          config.optimization = {
            splitChunks: {
              cacheGroups: {
                common: {
                  name: "chunk-common",
                  chunks: "initial",
                  minChunks: 2,
                  maxInitialRequests: 5,
                  minSize: 0,
                  priority: 1,
                  reuseExistingChunk: true,
                  enforce: true
                },
                vendors: {
                  name: "chunk-vendors",
                  test: /[\\/]node_modules[\\/]/,
                  chunks: "initial",
                  priority: 2,
                  reuseExistingChunk: true,
                  enforce: true
                },
                elementUI: {
                  name: "chunk-elementui",
                  test: /[\\/]node_modules[\\/]element-ui[\\/]/,
                  chunks: "all",
                  priority: 3,
                  reuseExistingChunk: true,
                  enforce: true
                },
                echarts: {
                  name: "chunk-echarts",
                  test: /[\\/]node_modules[\\/](vue-)?echarts[\\/]/,
                  chunks: "all",
                  priority: 4,
                  reuseExistingChunk: true,
                  enforce: true
                }
              }
            }
          };
        }
        config.plugins = [...config.plugins, ...plugins];
      }
    
    1. 去除consollog
      configureWebpack: config => {
        const plugins = [];
        if (isProduction) {
          // 去除consollog
          plugins.push(
            new UglifyJsPlugin({
              uglifyOptions: {
                compress: {
                  warnings: false,   // 打包报错可注掉
                  drop_console: true,
                  drop_debugger: false,
                  pure_funcs: ["console.log"] //移除console
                },
              },
              sourceMap: false,
              parallel: true,
            })
          );
        }
        config.plugins = [...config.plugins, ...plugins];
      }
    

    设置完后,打包后可以看到 .gz 结尾的文件,在http请求的Request Headers 中能看到 Accept-Encoding:gzip。
    要使服务器返回.gz文件,还需要对服务器进行配置,根据Request Headers的Accept-Encoding标签进行鉴别,如果支持gzip就返回.gz文件。

    完整vue.config.js
    const path = require('path');
    const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
    const CompressionWebpackPlugin = require('compression-webpack-plugin');
    const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;
    // 生产环境名称
    const isProduction = ["production", "prod"].includes(process.env.NODE_ENV);
    const resolve = dir => path.join(__dirname, dir);
    module.exports = {
      publicPath: '/',    // 公共路径
      runtimeCompiler: true, // 是否使用包含运行时编译器的 Vue 构建版本
      outputDir: process.env.NODE_ENV === "development" ? 'devdist' : 'dist', // 不同的环境打不同包名
      pluginOptions: {
        "style-resources-loader": {
          preProcessor: "less",
          patterns: [
            // 这个是加上自己的路径,
            // 注意:试过不能使用别名路径
            path.resolve(__dirname, "./src/assets/css/variable.less")
          ]
        }
      },
      lintOnSave: false,  // 关闭eslint
      productionSourceMap: false,  // 清楚 .map 文件
      devServer: {   // 配置服务器
        port: 8111,
        open: true,
        https: false,
        proxy: {
          '/api/*': {
            target: process.env.VUE_APP_URL,    // 目标 API 地址
            ws: true,                               // 是否代理 websockets
            changOrigin: true,                      // 跨域配置
            pathRewrite: {
              '^/api': '/'
            }
          }
        }
      },
      // webpack配置
      chainWebpack: (config) => {
        // 别名路径
        config.resolve.alias
          .set('@', resolve('src'))
          .set('@i', resolve('src/assets/image'))
          .set('@s', resolve('src/assets/css'))
          .set('@j', resolve('src/assets/js'))
        if (isProduction) {
          config.optimization.delete("splitChunks");
        }
        return config;
      },
      // 配置webpack
      configureWebpack: config => {
        const plugins = [];
        if (isProduction) {
          // 开启gzip压缩
          plugins.push(
            new CompressionWebpackPlugin({
              filename: "[path].gz[query]",
              algorithm: "gzip",
              test: productionGzipExtensions,
              threshold: 10240,
              minRatio: 0.8
            })
          );
          // 利用 splitChunks 单独打包第三方模块
          config.optimization = {
            splitChunks: {
              cacheGroups: {
                common: {
                  name: "chunk-common",
                  chunks: "initial",
                  minChunks: 2,
                  maxInitialRequests: 5,
                  minSize: 0,
                  priority: 1,
                  reuseExistingChunk: true,
                  enforce: true
                },
                vendors: {
                  name: "chunk-vendors",
                  test: /[\\/]node_modules[\\/]/,
                  chunks: "initial",
                  priority: 2,
                  reuseExistingChunk: true,
                  enforce: true
                },
                elementUI: {
                  name: "chunk-elementui",
                  test: /[\\/]node_modules[\\/]element-ui[\\/]/,
                  chunks: "all",
                  priority: 3,
                  reuseExistingChunk: true,
                  enforce: true
                },
                echarts: {
                  name: "chunk-echarts",
                  test: /[\\/]node_modules[\\/](vue-)?echarts[\\/]/,
                  chunks: "all",
                  priority: 4,
                  reuseExistingChunk: true,
                  enforce: true
                }
              }
            }
          };
          // 去除consollog
          plugins.push(
            new UglifyJsPlugin({
              uglifyOptions: {
                compress: {
                  // warnings: false,
                  drop_console: true,
                  drop_debugger: false,
                  pure_funcs: ["console.log"] //移除console
                },
              },
              sourceMap: false,
              parallel: true,
            })
          );
          config.externals = {
          }
        }
        config.plugins = [...config.plugins, ...plugins];
      }
    }
    

    相关文章

      网友评论

        本文标题:vue-cli3 打包优化

        本文链接:https://www.haomeiwen.com/subject/tmmacktx.html