Vue 打包体积优化方案

·  阅读 5818

Vue-cli3 打包体积优化方案


前言:

公司项目完成后 ,打包完成后有1.18MB,其实感觉还行了,但是还可以有优化的地方,对于咱们有精益求精(有没有还是有点*数的)的精神下再去优化,可以先在项目中安装 webpack-bundle-analyzer 可以看到各个文件的大小

npm install webpack-bundle-analyzer -save-dev
复制代码
在vue.config.js中进行配置
module.exports = {
    chainWebpackconfig => {
        config
        .plugin('webpack-bundle-analyzer')
        .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
    }
}
复制代码

执行npm run build 或者 npm run serve 会出现这花里胡哨的界面用来分析文件大小

分析

还没进行优化前vendor~app.xxxx.js 有1.18MB,咱们可以查看各个bundle大小,针对性的进行优化

优化

  • CDN加载

    对于vue、vue-router、vuex、axios等都可以在生产环境用CDN加载

    const externals = {
      'vue''Vue',
      'vue-router''VueRouter',
      'vuex''Vuex',
      'axios''axios'
    }
    const cdn = {
      css: [],
      js: [
        'https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js',
        'https://cdn.jsdelivr.net/npm/vue-router@3.0.1/dist/vue-router.min.js',
        'https://cdn.jsdelivr.net/npm/vuex@3.0.1/dist/vuex.min.js',
       'https://cdn.jsdelivr.net/npm/axios@0.18.0/dist/axios.min.js',
      ]
    }

    module.exports = {
      chainWebpackconfig => {
          config
          .plugin('webpack-bundle-analyzer')
          .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
          config.plugin('html').tap(args => {
          if (process.env.NODE_ENV === 'production') {
            args[0].cdn = cdn
          }
          return args
        })
      },
    configureWebpackconfig => {
        if (process.env.NODE_ENV === 'production') {
            return {
              externals: externals,
            };
         }
      },
    }
    复制代码

    接着修改pubilc/index.html文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width,initial-scale=1.0">
      <link rel="icon" href="<%= BASE_URL %>favicon.png">
      <!-- 使用CDN的CSS文件 -->
      <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
      <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="external nofollow" rel="external nofollow" rel="preload" as="style">
      <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="external nofollow" rel="external nofollow" rel="stylesheet">
      <% } %>
      <!-- 使用CDN的JS文件 -->
      <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
        <link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="external nofollow" rel="preload" as="script">
      <% } %>
      <title>上海比户</title>
    </head>
    <body>
      <noscript>
        <strong></strong>
      </noscript>
      <div id="app"></div>
      <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
        <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
      <% } %>
    </body>
    </html>
    复制代码

    看图片已经为700多k了,直接减少了400多k

  • 路由懒加载

    当打包应用的时候,JavaScript包会变的特别大,影响页面加载,如果这时我们在访问路由的时候去加载该模块,那会变的十分高效,把静态引入方式改为动态引入方式

    import ComponentA from '../page/components/ComponentA';
    routeList = [
        {
          path'/comA',
          component: ComponentA
        },
    ]

    //改为
    routeList = [
        {
          path'/comA',
          component() => import('../page/components/ComponentA')
        },
    ]
    复制代码

    由于我的项目一开始就用了路由懒加载,所以在打包文件上看不出体积大小的变化,但是大概会有个300k的大小减少

    在vue cli3中,我们还需要手动移除 prefetchPreload ,因为在vue cli 官方文档上提到,可以去了解下,我这大致概括了下

    就是当首屏加载的时候,会一次性下载完所以的路由文件,这会导致首屏的时候请求内容变多,首屏加载变慢,修改如下

    module.exports = {
      chainWebpackconfig => {
          config
          .plugin('webpack-bundle-analyzer')
          .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
           config.plugin('html').tap(args => {
           if (process.env.NODE_ENV === 'production') {
              args[0].cdn = cdn
           }
           return args
         })
          // 移除 prefetch 插件
          config.plugins.delete('prefetch')
          // 移除 preload 插件
          config.plugins.delete('preload');
      },
      configureWebpackconfig => {
          if (process.env.NODE_ENV === 'production') {
             return {
               externals: externals,
             };
          }
      },
    }
    复制代码
  • element-ui 按需加载

    看element-ui/lib 这个包就占了总包大小的三分之二,554k,总包也就700多k,所以如果把element-ui 按需加载,那就可以减少体积,按需加载这就不说了吧,都会~😝

    但是需要在 babel.config.js文件中添加(vue cli3 中需要安装 babel-plugin-component)

    module.exports = {
        presets: ['@vue/app'],

       //加上这~
       plugins: [
          [
            'component',
            {
              libraryName'element-ui',
              styleLibraryName'theme-chalk'
            }
          ]
       ]
    };
    复制代码
  • gzip

    安装 compression-webpack-plugin

    nmp i compression-webpack-plugin -D
    复制代码

    在vue.config.js中引入

    const CompressionPlugin = require('compression-webpack-plugin');

    module.exports = {
        chainWebpackconfig => {
            config
            .plugin('webpack-bundle-analyzer')
            .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
             config.plugin('html').tap(args => {
               if (process.env.NODE_ENV === 'production') {
                 args[0].cdn = cdn
               }
               return args
            })
            // 移除 prefetch 插件
            config.plugins.delete('prefetch')
            // 移除 preload 插件
            config.plugins.delete('preload');
          },
          configureWebpackconfig => {
            if (process.env.NODE_ENV === 'production') {
              return {
                externals: externals,
                plugins: [
                  //gzip压缩
                  new CompressionPlugin({
                    test/\.js¨E92E.html|\.html¨E92E.html|.\css///匹配文件名
                    threshold: 10240//对超过10k的数据压缩
                    deleteOriginalAssets: false //不删除源文件
                  })
                ],
                performance: {
                  hintsfalse
                }
              };
           }
        },
    }
    复制代码

    可以在上面的图看到,进行gzip压缩后的文件最大的也只有140k了

    但是还需要在服务端配置

  • scss文件引入

    我们通常会把scss文件抽离出来,一些共用样式,主题等,然后会在每个需要的组件中引入会显得繁琐,我们可以借助scss-loader进行预处理

    例如我们有 resetTable.scss 文件,可以在vue.config.js中引入

    module.exports = {
        chainWebpackconfig => {
           config
           .plugin('webpack-bundle-analyzer')
           .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
           config.plugin('html').tap(args => {
             if (process.env.NODE_ENV === 'production') {
                args[0].cdn = cdn
              }
              return args
            })
            // 移除 prefetch 插件
            config.plugins.delete('prefetch')
            // 移除 preload 插件
            config.plugins.delete('preload');
          },
        configureWebpackconfig => {
           if (process.env.NODE_ENV === 'production') {
             return {
               externals: externals,
               plugins: [
                 //gzip压缩
                 new CompressionPlugin({
                   test/\.js¨E92E.html|\.html¨E92E.html|.\css///匹配文件名
                   threshold: 10240//对超过10k的数据压缩
                   deleteOriginalAssets: false //不删除源文件
                 })
               ],
               performance: {
                 hintsfalse
               }
            };
          }
       },
       // scss设置
       css: {
         loaderOptions: {
           sass: {
             //我是放在 assets/commcss 目录下
             data: '@import "@assets/commcss/resetTable.scss";'
           }
         },
       },
    }
    复制代码

    上面这图就是完整的vue.config.js配置啦~

总结:

​ 以上就是目前我在项目中优化的点,但肯定还有其他的优化地方,可以相互讨论

向着风 拥抱彩虹 勇敢的向前走~ 😬
分类:
前端
标签:
分类:
前端
标签: