打包信息可视化

66 阅读5分钟

打包信息可视化

  1. webpack-bundle-analyzer

    • webpack-bundle-analyzer 是一个独立的 webpack 插件,用于分析 webpack 打包生成的 bundle 文件。
    • 你需要将它添加到 webpack 配置中,并在构建过程中生成一个分析报告,通常是一个交互式的可视化报告,用于查看应用程序的各个模块的大小和依赖关系。
    • 这个工具不仅可以用于 Vue.js 项目,还可以用于任何使用 webpack 打包的前端项目,不限于 Vue.js。
  2. vue build --report/vue build --report-json

    • vue build --report 是 Vue CLI 提供的一个命令,用于在构建 Vue.js 项目时生成构建报告。
    • 这个命令会生成一个报告文件,通常是一个 HTML 文件,其中包含了构建过程中的各种信息,包括各个模块的大小、依赖关系、构建时间等。
    • 这个命令是专门为 Vue.js 项目设计的,它利用了 Vue CLI 内部的一些功能来生成报告。

        虽然这两种工具都可以用于分析项目的打包情况,但它们的使用方式和输出结果略有不同。webpack-bundle-analyzer 更加通用,适用于各种 webpack 构建的项目,而 vue build --report 更加针对 Vue.js 项目,并且提供了与 Vue CLI 集成的便利性。

如果你是在 Vue.js 项目中使用 Vue CLI,推荐使用 vue build --report 命令来生成构建报告,因为它可以更好地与 Vue CLI 集成,提供更丰富的信息。如果你需要在其他项目中进行分析,可以考虑使用 webpack-bundle-analyzer 插件。

这是配置命令和打包后dist文件中有一个report.html

image.png 打开就是包的可视化图。

image.png

这是前台试题网包的情况,没有很大很臃肿的包,说明大家开发过程中各种优化做的很好。

总结一些常见的给包瘦身的优化手段:

1.externals 提取项目依赖

**
**项目里总会有一些公共的包,类似vue,vue-router,axios,echarts等等,可以使用 externals 来提取这些依赖包,告诉 webpack 这些依赖是外部环境提供的,在打包时可以忽略它们,就不会再打到 chunk-vendors.js 中。

1)vue.config.js 中配置:

image.png

2)在 index.html 中使用 CDN 引入依赖

image.png

2、组件库的按需引入

为什么没有使用 externals 的方式处理组件库呢?

externals缺点:直接在html内引入的,失去了按需引入的功能,只能引入组件库完整的js和css

组件库按需引入的原理:最终只引入指定组件和对应的样式

elementUI 需要借助 babel-plugin-component 插件实现,插件的作用如下:

如按需引入 Button 组件:

image.png

编译后的文件(自动引入 button.css):

image.png

通过该插件,最终只引入指定组件和样式,来实现减少组件库体积大小

1)安装 babel-plugin-component

       npm install babel-plugin-component -D

2)babel.config.js中引入

image.png

3、减小三方依赖的体积

项目中使用了 momentjs,发现打包后有很多没有用到的语言包

image.png

使用 moment-locales-webpack-plugin 插件,剔除掉无用的语言包

1)安装

npm install moment-locales-webpack-plugin -D 安装

2)vue.config.js 中引入 

const MomentLocalesPlugin = require('moment-locales-webpack-plugin');

优化前: image.png

优化后:没找到moment呢个语言包  不知道是不是给优化掉了...包总体减少了0.23M,蚂蚁在小也是肉~ image.png image.png

4、HappyPack 多线程打包

由于运行在 Node.js 之上的 webpack 是单线程模型的,我们需要 webpack 能同一时间处理多个任务,发挥多核 CPU 电脑的威力

HappyPack 就能实现多线程打包,它把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程,来提升打包速度

1)安装

npm install HappyPack -D

2)vue.config.js 中引入

image.png

然后打包测试一下

image.png

加速了8s,还可以。

image.png

5、Gzip压缩

线上的项目,一般都会结合构建工具 webpack 插件或服务端配置 nginx,来实现 http 传输的 gzip 压缩,目的就是把服务端响应文件的体积尽量减小,优化返回速度

html、js、css资源,使用 gzip 后通常可以将体积压缩70%以上

这里介绍下使用 webpack 进行 gzip 压缩的方式,使用 compression-webpack-plugin 插件

1)安装

npm install compression-webpack-plugin -D

2)vue.config.js 中引入

image.png

6、DllPlugin 动态链接库

DllPlugin 与 externals 的作用相似,都是将依赖抽离出去,节约打包时间。区别是 DllPlugin 是将依赖单独打包,这样以后每次只构建业务代码,而 externals 是将依赖转化为 CDN 的方式引入

当公司没有很好的 CDN 资源或不支持 CDN 时,就可以考虑使用 DllPlugin ,替换掉 externals

DllPlugin 配置流程大致分为三步:

1)创建 dll.config.js 配置文件

image.png

2)package.json 配置脚本

image.png

3)使用 DllReferencePlugin 将打包生成的dll文件,引用到需要的预编译的依赖上来,并通过 html-webpack-tags-plugin 在打包时自动插入dll文件

vue.config.js 配置如下

image.png

先运行 npm run build:dll 打包生成依赖文件,以后只用运行 npm run build 构建业务代码即可

7. 静态图片压缩处理

安装:npm i image-webpack-loader -D

如下配置:

chainWebpack: config => {
  if(IS_PROD){
    config.module
      .rule('images')
        .exclude.add(resolve('src/assets/icons')) // 排除icons目录,这些图标已用 svg-sprite-loader 处理,打包成 svg-sprite 了
        .end()
        .use('url-loader')
          .tap(options => ({
            limit: 10240, // 稍微改大了点
            fallback: {
              loader: require.resolve('file-loader'),
              options: {
                // 在这里修改file-loader的配置
                // 直接把outputPath的目录加上,虽然语义没分开清晰但比较简洁
                name: 'static/img/[name].[hash:8].[ext]'
                // 从生成的资源覆写 filename 或 chunkFilename 时,`assetsDir` 会被忽略。
                // 因此别忘了在前面加上静态资源目录,即assetsDir指定的目录,不然会直接在dist文件夹下
                // outputPath: 'static/img' 
              }
            }
        }))
        .end()
        .use('image-webpack-loader')
          .loader('image-webpack-loader')
          .options({
            mozjpeg: { progressive: true, quality: 50 }, // 压缩JPEG图像
            optipng: { enabled: true }, // 压缩PNG图像
            pngquant: { quality: [0.5, 0.65], speed: 4 }, // 压缩PNG图像
            gifsicle: { interlaced: false } // 压缩GIF图像
          })
          .end()
          .enforce('post') // 表示先执行配置在下面那个loader,即image-webpack-loader
  }
}