vue2项目dist瘦身——打包体积压缩73%、速度提升90%


背景

随着前端技术的不断发展,网页应用程序变得越来越复杂,并且需要更多的资源来加载和运行。在使用 Vue2 构建的项目中,打包后的文件大小可能会非常大。

我的一个可视化系统项目,文件约1302个、有效代码行数约 257217行、项目整体资源算是比较多。

image.png

主要技术栈:vue-cli3、vue2、vuex、axios、webpack4、echarts、less等

这么多内容就会导致在打包时出现 构建速度慢、构建产物体积庞大的问题

遇到紧急情况需要最快速度发版时,项目打包时间高达4-5分钟,同时如果使用ftp工具上传源码时,由于打包产物体积过大,也会影响上传速度!

打包速度慢、体积庞大成了项目的痛点。
本文介绍了一些针对 Vue2 项目的打包瘦身策略,在瘦身的这个过程中我也在网上学习了很多资料,谨以此篇记录我的一次项目优化学习、实践的过程。

如果文章对你有帮助,可以点赞、评论、收藏、转发互动支持哈😀😀😀
点击链接 学习交流群(前端微信群) 加vx拉你进 前端学习交流群 让我们一起 好好学习(🐟🐟🐟)吧😎😎😎

打包体积优化

优化前:dist包大小为207.8mb,相当大!

image.png

字体文件大小优化

常见字体格式
不推荐:

  • eot:IE系列专属字体方案
  • ttf:兼容性好,但是字体文件较大
  • svg:不是真的字体,存在很多兼容问题(IE古老浏览器)

推荐:

  • woff:W3C标准,兼容性好
  • woff2:W3C标准,但是不兼容IE

关于字体大小优化,网上看到的方案大部分都是使用字蛛、Fontmin、或者放cdn处理。
我没有尝试,我这里直接使用了在线转换工具先将大文件转换为woff格式(以后直接找ui给我们woff格式的字体文件,会小很多)
Convertio — 文件转换器

如果大家有什么更优雅处理字体文件过大的方案欢迎评论区讨论!

初始字体大小 29.5mb:
image.png

转换三个比较大的字体为woff格式后18.1mb:
image.png

图片优化

由于项目中图片用的比较多、打包后图片文件很大导致dist包体积很大,这时候想通过webpack插件去处理图片资源、从而瘦身dist包体积。

  • url-loader

    这里踩过坑,详情请移步:url-loader图片不显示、不报错踩坑 - 掘金 (juejin.cn)

    用url-loader转换图片为base64(图片打包成字符串,放到js中),减少文件请求次数。

    问题:
    这种方式仅适合于比较小的图片资源,如果一个图片文件很大这样又会导致构建出的 .js 文件变大,导致加载缓慢。所以需要配合 image-webpack-loader 使用

  • image-webpack-loader

    使用url-loader的 limit 字段控制指定大小图片才转base64(我这里也使用url-loader处理了字体文件)
    然后使用 image-webpack-loader 来压缩超过limit阈值的大图片。这样就是小图片转base64、大图片压缩完还打包到指定路径中。

    yarn add -D url-loader image-webpack-loader

    ps:image-webpack-loader下载失败可以尝试用cnpm

     configureWebpack: {
          module: {
            rules: [
                  {
                    test: /\.(png|jpe?g|gif|webp)(\?.*)?$/i,
                    exclude: /node_modules/,
                    include: path.resolve('src'),
                    use: [
                      {
                        loader: 'url-loader',
                        options: {
                          esModule: false, // 不转换esm规范
                          name: 'img/[name].[hash:2].[ext]',
                          limit: 1024 * 12
                        }
                      },
                      {
                        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图像
                          // webp: { quality: 75 } // 压缩webp
                        }
                      }
                    ]
                  }
                ]
              },
            },

    字体+图片处理后此时的dist包体积:80.5mbdist包体积压缩提升60%

    image.png
    此时打包速度为:289s

    image.png

前端开启Gzip压缩

  • compression-webpack-plugin (Gzip压缩)

    nginx可以启动静态和动态压缩,如果能在Vue打包过程就压缩好,就可以缓解一些服务器CPU的压力。该插件可以打包文件压缩为.gz格式(最终发布生产环境时需要nginx配置开启gzip才能生效)

    ps: 插件版本需要和webpack匹配对应
    yarn add -D compression-webpack-plugin

     configureWebpack: {
          plugins: [
                // gizp压缩
                new CompressionWebpackPlugin({
                  test: /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i,
                  threshold: 10240, // 对10K以上的数据进行压缩
                  deleteOriginalAssets: true
                })
          ]
        },

    gzip压缩后此时dist包:56.8mb,观察发现js等其他文件夹对应文件也压缩了不少(且生成了.gz文件)

    此时相比首次dist包体积207.8mb,我们做到了压缩提升73%
    image.png
    此时打包速度:302s
    image.png

nginx配置开启gzip

前端项目配置了gzip压缩、且删除原文件后部署访问404
image.png
这时候就需要nginx 配置开启gzip了

  • nginx配置:

      #开启gzip功能
      gzip on; 
      #开启gzip静态压缩功能
      gzip_static on; 
      #gzip缓存大小
      gzip_buffers 4 16k;
      #gzip http版本
      gzip_http_version 1.1;
      #gzip 压缩级别 1-10 r
      gzip_comp_level 5;
      #gzip 压缩类型
      gzip_types text/plain application/javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
      #配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持
      gzip_disable   "MSIE [1-6]\.";
  • gzip_static的作用

    nginx在设置了gzip on 后就已经打开了gzip压缩功能,不过这时候nginx所使用的是动态压缩。在动态压缩的情况下nginx会自动的将文件压缩成.gz文件,这时候就算不配置vue也能达到一样的效果。
    但是动态压缩无疑会占用服务器的资源来进行此操作。

    nginx也提供了静态压缩模式,也就是gzip_static,在这个模式下nginx会去寻找对应文件的.gz文件,只有.gz文件不存在的时候才会去压缩对应文件,这样就不会过度占用服务器资源。

    最后访问部署地址后查看http请求看到content-Encodeing: gzip 就代表gzip已经成功开启了

    image.png

打包速度优化

处理完打包体积后,来看看此时的打包速度:
255s还是比较慢的,现在这个配置我这台机器打包时间基本上都在250-300s
image.png

合理使用缓存cache-loader

Webpack4 中还可以使用 cache-loader 实现与 Webpack5 相似的通用持久化缓存功能。仅需要在一些性能开销较大的 loader 之前添加此 loader
cache-loader 缓存的是对应loader的处理结果,将结果缓存到磁盘里,显著提升二次构建速度。

安装:yarn add -D cache-loader
这里我在处理图片的image-webpack-loader前使用。

刚开始在url-loader前使用时发现二次打包后部分图片会丢失,部署后部分图片404(尚未解决!)如果有大佬遇到过希望评论区指点!

   configureWebpack: {
        module: {
          rules: [
                {
                  test: /\.(png|jpe?g|gif)(\?.*)?$/,
                  use: [
                    {
                      loader: 'url-loader',
                      options: {
                        name: 'img/[name].[hash:6].[ext]',
                        limit: 10 * 1024
                      }
                    },
                    {
                      loader: 'cache-loader'
                    },
                    {
                      loader: 'image-webpack-loader'
                    }
                  ]
                }
          ]
        },
      },

这时第一次打包速度来到了23s,相比上面的的250s 打包速度提升了约90%
image.png

再次打包速度:19s
image.png

再次打包速度:23s
image.png

使用缓存后基本上打包速度都在20s左右,终于可以和漫长的打包时间说拜拜啦!

关于启动速度

开发环境不配置任何loader、plugins启动时间:
14s
image.png
13s
image.png

配置后:45s
image.png

这里我使用了npm 和 yarn 分别多次启动测试发现时间都不一样。拿我的win(运行内存16g、磁盘1.5g)跑的话有时候竟然高达6位数,烦躁的很!可能电脑配置不行吧,每次起这个项目风扇就起飞了、有时候还会出现卡顿😂 条件允许还是上mac吧,真挺丝滑的。

经过多次测试,我发现开发环境如果也配置一些loader、plugins 后会增加启动时间,得不偿失。 没有上vite是因为项目内容太多了,改造成本太高。新项目的话还是建议直接vite吧,不得不说还是vite开发丝滑呀!

所以我这里开发环境直接不配置任何loader、plugins。然后区分开发环境,加载不同配置文件。

因为项目默认用的是vue-cli-service服务,当执行npm run buildnpm run dev时可以在config文件中通过process.env.NODE_ENV获取到当前环境

先在根目录创建config目录,再分别创建webpack.prod、webpack.dev配置文件,分别配置后通过module.exports暴露出来。

最后根目录`vue.config.js`文件根据不同环境引入:
```js
console.log('当前环境:', process.env.NODE_ENV)
const config = process.env.NODE_ENV === 'production' ? require('./config/webpack.prod') : require('./config/webpack.dev')

module.exports = {
  ...config
}
```

vue2项目随着版本的迭代,资源越来越多,启动时速度就越来越慢,如果业界大佬有什么好的解决方案能够解决vue2+webpack4老项目启动速度问题,欢迎评论区指点!

总结

经过上述一系列操作配置后最终结果如下:

  • 打包体积由开始的207.8MB -> 优化到56.8MB,提升约 73%
  • 打包速度由250s -> 优化到约20s,提升约 90%

本次瘦身之旅,只尝试了这部分内容,总体来说还是有效果的。很多知识仅仅停留在熟悉、了解还不够,最终还是要亲自去实践才能真正学习和掌握。

我相信肯定还有很多优化方案、方向,学无止境,欢迎大家评论区讨论交流。


文章作者: 尖椒土豆sss
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 尖椒土豆sss !
 上一篇
vue2应用性能优化:首屏FCP指标提升约80% vue2应用性能优化:首屏FCP指标提升约80%
背景一个vue2的项目,打包部署后,发现首屏加载速度慢,FCP白屏时间大约需要8s左右,从输入系统地址按下回车后,就一直转啊转啊转,加载缓慢,导致用户的体验非常不好!所以今天针对这个问题来做一些性能优化。 期望的结果就是首屏加载速度快一点,
下一篇 
pnpm报错:/gifsicle  postinstall$ node lib/install.js pnpm报错:/gifsicle postinstall$ node lib/install.js
遇到问题最近在使用 pnpm 安装依赖时遇到了报错,死活都下载不下来。 pnpm add xxx 或者 pnpm i 都报错如下:.../node_modules/gifsicle postinstall$ node lib/instal
2023-03-16 尖椒土豆sss
  目录
L
O
A
D
I
N
G