Vue项目打包优化

作者: 神话降临 | 来源:发表于2022-01-20 17:39 被阅读0次

    目的

    缩小项目打包体积,提高页面加载速度

    分析产生效果慢的原因

    我们先来分析下前端加载速度慢原因

    1. 首先安装webpack的可视化资源分析工具,命令行执行:
    npm i webpack-bundle-analyzer -D
    
    1. 然后在webpack的dev开发模式配置中,引入插件,代码如下:
    const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
    // 或者使用chainWebpack
    chainWebpack: config => {
    if(process.env.NODE_ENV === 'development') {
          config.plugin('BundleAnalyzerPlugin')
          .use(BundleAnalyzerPlugin)
        }
    }
    

    3.执行npm run serve , 浏览器会自动打开分析结果,如下所示:


    效果图.png

    从图中可以看出来,有几块是体积比较大的,我们就着重优化这些体积大的块

    有针对性的优化方案

    一、vue-cli从版本3升级到版本4的时候,新增了webpack的一些配置,其中就包括splitChunks,如下所示,所以我们在优化的时候,就不用在vue.config.js里写代码分割相关的配置了。

    optimization: {
        splitChunks: {
          chunks: 'async',
          minSize: 30000,
          minChunks: 1,
          maxAsyncRequests: 5,
          maxInitialRequests: 3,
          automaticNameDelimiter: '~',
          name: true,
          cacheGroups: {
            common: {
              name: 'chunk-commons',
              chunks: chunks(chunk) { },
              test: function () { /* omitted long function */ },
              priority: 10,
              minChunks: 2,
              reuseExistingChunk: true,
              enforce: true
            }
          }
        }
      },
    

    查看全部脚手架默认webpack配置,输入如下命令

    vue inspect > output.js
    

    二、对于第三方js库的优化,分离打包
    从上面的打包效果图可以看出来,几个比较大的包分别是,vue、element,echarts等,既然找到了问题,我们就可以通过webpack的externals配置,来打包分离第三方资源包
    key为依赖包名称,value是源码抛出来的全局变量。如下图所示,这样webpack就不会打包这些外部的包了。

    chainWebpack: config => {
        if(process.env.NODE_ENV === 'development') {
          config.plugin('BundleAnalyzerPlugin')
          .use(BundleAnalyzerPlugin)
        }
    // 新增externals配置
         config.set('externals',{
          vue: 'Vue',
          'vuex': 'Vuex',
          'vue-router': 'VueRouter',
          'element-ui':'ELEMENT',
          'echarts': 'echarts'
      })
    }
    

    写了上述配置后,还需要在public/index.html里面引入这些不被打包的第三方资源包。
    注意把 xx.js 换成 xx.min.js,这是一个更小的构建,可以带来比开发环境下更快的速度体验。
    以下是可以访问cdn和不可以访问cdn的两个配置:
    第一种:可以通过网络访问cdn

     <body>
        <noscript>
          <strong>We're sorry but vue-ul-admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
        </noscript>
        <div id="app"></div>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.min.js"></script>
        <script src="https://cdn.bootcdn.net/ajax/libs/vuex/3.1.1/vuex.min.js"></script>
        <script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.0.6/vue-router.min.js"></script>
        <script src="https://cdn.bootcdn.net/ajax/libs/echarts/3.8.0/echarts.min.js"></script>
         <!-- 引入样式 -->
        <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
        <!-- 引入组件库 -->
        <script src="https://unpkg.com/element-ui/lib/index.js"></script>
      </body>
    

    然后删除main.js对于element主题的引入

    // 删除这个代码
    import 'element-ui/lib/theme-chalk/index.css'
    

    第二种:不能访问cdn的情况
    在node_module里面找到对应的资源文件,比如vue:


    1642645514(1).png

    把vue.min.js文件拷贝到public目录下。
    依次把所有需要external的包,按照上述步骤操作
    注意如果不能访问外部网络的情况下,想把element内容不被打包,则需要拷贝element/lib文件夹的所有内容到public目录下

    <script src="vue.min.js"></script>
    <script src="vuex.min.js"></script>
    <script src="vue-router.min.js"></script>
    <script src="echarts.min.js"></script>
    <!-- 引入样式 -->
    <link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
    <!-- 引入组件库 -->
    <script src="element-ui/lib/index.js"></script>   
    

    然后删除main.js对于element主题的引入

    // 删除这个代码
    import 'element-ui/lib/theme-chalk/index.css'
    

    三、配置js文件体积更小化

      chainWebpack: config => { 
        config.optimization
           .minimize(true)
    }
    

    四、图片压缩

    chainWebpack: config => { 
    config.module
          .rule('min-image')
          .test(/\.(png|jpe?g|gif)(\?.*)?$/)
          .use('image-webpack-loader')
          .loader('image-webpack-loader')
          .options({bypassOnDebug: true})
          .end()
    }
    

    五、开启gizp压缩
    gizp压缩是一种http请求优化方式,通过减少文件体积来提高加载速度。html、js、css文件甚至json数据都可以用它压缩,可以减小60%以上的体积。前端配置gzip压缩,并且服务端使用nginx开启gzip,用来减小网络传输的流量大小。
    安装

    // 如果安装报错,建议降低compression-webpack-plugin版本尝试
    npm i compression-webpack-plugin -D
    

    使用

    const CompressionWebpackPlugin = require('compression-webpack-plugin')
    chainWebpack: config => {
        if (process.env.NODE_ENV === 'production') {
          config.plugin("compressionPlugin").use(
            new CompressionPlugin({
              test: /\.js$|\.html$|\.css/, // 匹配文件名
              threshold: 10240, // 对超过10k的数据压缩
              deleteOriginalAssets: false, // 不删除源文件
            })
          );
        }
      }
    

    nginx也需要在http增加相关的配置

    http {
      ......
      # 开启gzip
      gzip on;
      # 启用gzip压缩的最小文件;小于设置值的文件将不会被压缩
      gzip_min_length 1k;
      # gzip 压缩级别 1-10 
      gzip_comp_level 2;
      # 进行压缩的文件类型。
      gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
      # 是否在http header中添加Vary: Accept-Encoding,建议开启
      gzip_vary on;
      
      server {
          listen       80;
          server_name  localhost;
          client_max_body_size 100m;
      
          ......
      }
    } 
    

    六、路由懒加载
    在访问到当前页面才会加载相关的资源,异步方式分模块加载文件,默认的文件名是随机的id,在页面加载时候,会加载对应的文件。

    {
        path: '/Login',
        name: 'Login',
        component: () = >import( /* webpackChunkName: "Login" */  '@/view/Login')
    }
    

    相关文章

      网友评论

        本文标题:Vue项目打包优化

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