前言

最近自己买个云服务器,把之前搭建的webpack-vue项目进行了部署,现在项目已经成功了。

项目地址:GitHub - wjt162286793/webpack----vue: 使用webpack配置一个脚手架,对照文档,纯手打

 线上地址:IAM架构资产管理系统

不过是没有经过任何优化的,虽然项目体积和业务不是很复杂,但是实际上打完包后体积也是比较大,首次加载也是需要请求大资源文件,导致项目加载很慢,而且还有很多console.log的内容在控制台上,效果如下

前端项目优化:减少webpack打包体积-LMLPHP

前端项目优化:减少webpack打包体积-LMLPHP

前端项目优化:减少webpack打包体积-LMLPHP

我这个项目最多算一个中小型,现在的包就87MB那么大,我在线上部署了一下,白屏16秒......

本文主要针对webpack进行优化,版本为webpack5,并不对业务代码本身进行优化,因为本身业务代码也不是特别的多,编写的时候也是注重代码的结构的

优化

1.拆包

用webpack打包后,vendors.js是所有当前项目中所有的依赖包和业务代码的综合,我们就要想办法让vendors包的提交大大缩减

(1)将每个业务组件分成单独的js文件

在配置路由时,我们可以使用懒加载和webpackChunkName,将每个路由组件都生成小包,脱离掉vendors.js

 {
   path: '/dashboard/business/businessList',
   name: 'businessList',
   meta: {
       name: '列表'
    },
   component: () => import(/* webpackChunkName:'businessList'*/ 'pages/business/components/businessList.vue')
    },

(2)使用externals筛除依赖包,改用cdn服务加载

注意:如果用户是可以连接到互联网的情况下,可以这样使用。如果用户是无法访问互联网和对应cdn地址的,就不可以这样去做了。

externals配置

当你使用了externals之后,里面配置的包就不会出现在打包中

  externals: {
    'vue': 'Vue',
    'axios': 'axios',
    'vue-router': 'VueRouter',
    'vuex': 'Vuex',
    'html2canvas': 'html2canvas',
    'lodash': '_'
  },

在项目中,我们引入的方式必须要要和这里面的一致

key是包名,value是这个包默认导出的名字(!!!一定要写对)

例如:vue3就没有导出vue,而是import {creatApp} from 'vue'

我们这里就要写成这个样子

//原来的写法
//import {createApp} from 'vue'

const Vue = require('vue')
import Main from './main.vue'
export const mainVue = Vue.createApp(Main)

其他同理

cdn的使用

如果我们使用externals排除了某个包,就需要在index.html中引入cdn地址。

这里注意,cdn的包地址一定要引对。

    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.3.4/vue.global.prod.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.5/axios.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/vuex/4.1.0/vuex.global.prod.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue-router/4.0.16/vue-router.global.prod.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/html2canvas/1.4.1/html2canvas.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

这里有一个很简单的测试方法,你去cdn地址上将代码复制下来,在本地去测一下,看能不能成功使用你在externals中使用的包类名

前端项目优化:减少webpack打包体积-LMLPHP

 前端项目优化:减少webpack打包体积-LMLPHP

 如果不能对的上,那你发到生产上就会报错

所以,找cdn的地址一定要找对

2.ui组件库的处理

大部分项目都会用到ui组件库,如element-ui或者element-plus,echarts等等

这里有一个原则,如果你的项目中基本把这个组件库的绝大多数组件都用了,那你就可以直接将这个组件库也用cdn的形式引用了。如果没有的话,那你就是用按需引入的方式去引入该ui组件库

大部分的组件库都给提供了按需引入的方式,对照着文档操作就可以了

3.依赖包的抽取

比如一个包在多个文件中使用,我们只需要抽取一次就可以了,这样也可以减除很多的冗余代码

    optimization: {
        moduleIds: 'deterministic',
        runtimeChunk: 'single',
        splitChunks: {
            cacheGroups: {
                vendor: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendors',
                    chunks: 'all',
                },
            },
        },
    },

4.使用gzip压缩

const CompressionPlugin = require('compression-webpack-plugin');
  plugins: [
    new CompressionPlugin({
      algorithm: 'gzip', // 使用gzip算法进行压缩
      test: /\.(js|css)$/, // 需要压缩的文件类型
      threshold: 10240, // 文件大小大于10KB才会被压缩
      minRatio: 0.8, // 压缩比例达到0.8才会被压缩
      deleteOriginalAssets: false, // 是否删除原始文件
    }),
    //...
  ],

使用了gzip之后,打包后的文件就会生成.gz的压缩文件,也是常见有效的优化,能是构建包更轻量

5.生产环境去掉debug,注释,打印语句

const TerserPlugin = require('terser-webpack-plugin');
  optimization: {
    //生产环境上干掉所有的js注释和日志
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          format: {
            comments: false,   //删除注释
          },
          compress: {
            drop_debugger: true,
            drop_console: true,
            pure_funcs: ['console.log']//删除打印语句
          }
        },
        extractComments: false,

      }),
    ],
  },

6.生产环境去除sourceMap

在开发的时候,我们为了方便查找错误,配置了soureMap。

但是在打包构建的时候,就需要关闭sourceMap了。其一是可以不打包map文件减少体积,其二是可以避免源码泄露。

在配置中加一行

devtool: false

7.对其他静态资源的压缩

在打包时,js文件会默认压缩。但是很多静态文件之类的不会,特别是图片等资源。

这里我就不在文档中写具体怎么操作了,网上一搜一大把。后续我会在webpack系列中对各种plugin进行演示

结果

现在我在打包一次,可以看看效果

前端项目优化:减少webpack打包体积-LMLPHP

 前端项目优化:减少webpack打包体积-LMLPHP

 效果也是很明显的

前端项目优化:减少webpack打包体积-LMLPHP

项目地址

特意说明一下:现在项目也只是完成了初版的,后续还有东西要往里面写。优化还有一些提升的空间

业务也都是模拟的假业务,是为了技术练习,没有任何的实际意义,也没有侵犯任何单位的行为。

项目地址:GitHub - wjt162286793/webpack----vue: 使用webpack配置一个脚手架,对照文档,纯手打

线上地址:IAM架构资产管理系统

感觉有用的在github上给个star吧!

01-13 09:17