背景
随着前端技术的不断发展,网页应用程序变得越来越复杂,并且需要更多的资源来加载和运行。在使用 Vue2 构建的项目中,打包后的文件大小可能会非常大。
我的一个可视化系统项目,文件约1302个、有效代码行数约 257217行、项目整体资源算是比较多。
主要技术栈:vue-cli3、vue2、vuex、axios、webpack4、echarts、less等
这么多内容就会导致在打包时出现 构建速度慢、构建产物体积庞大的问题
遇到紧急情况需要最快速度发版时,项目打包时间高达4-5分钟,同时如果使用ftp工具上传源码时,由于打包产物体积过大,也会影响上传速度!
打包速度慢、体积庞大成了项目的痛点。
本文介绍了一些针对 Vue2 项目的打包瘦身策略,在瘦身的这个过程中我也在网上学习了很多资料,谨以此篇记录我的一次项目优化学习、实践的过程。
如果文章对你有帮助,可以点赞、评论、收藏、转发互动支持哈😀😀😀
点击链接 学习交流群(前端微信群) 加vx拉你进 前端学习交流群 让我们一起 好好学习(🐟🐟🐟)吧😎😎😎
打包体积优化
优化前:dist包大小为207.8mb,相当大!
字体文件大小优化
常见字体格式
不推荐:
- eot:IE系列专属字体方案
- ttf:兼容性好,但是字体文件较大
- svg:不是真的字体,存在很多兼容问题(IE古老浏览器)
推荐:
- woff:W3C标准,兼容性好
- woff2:W3C标准,但是不兼容IE
关于字体大小优化,网上看到的方案大部分都是使用字蛛、Fontmin、或者放cdn处理。
我没有尝试,我这里直接使用了在线转换工具先将大文件转换为woff格式(以后直接找ui给我们woff格式的字体文件,会小很多)
Convertio — 文件转换器
如果大家有什么更优雅处理字体文件过大的方案欢迎评论区讨论!
初始字体大小 29.5mb:
转换三个比较大的字体为woff格式后18.1mb:
图片优化
由于项目中图片用的比较多、打包后图片文件很大导致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
下载失败可以尝试用cnpmconfigureWebpack: { 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.5mb, dist包体积压缩提升60%
此时打包速度为:289s
前端开启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%
此时打包速度:302s
nginx配置开启gzip
前端项目配置了gzip压缩、且删除原文件后部署访问404
这时候就需要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已经成功开启了
打包速度优化
处理完打包体积后,来看看此时的打包速度:
255s还是比较慢的,现在这个配置我这台机器打包时间基本上都在250-300s
合理使用缓存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%
再次打包速度:19s
再次打包速度:23s
使用缓存后基本上打包速度都在20s左右,终于可以和漫长的打包时间说拜拜啦!
关于启动速度
开发环境不配置任何loader、plugins启动时间:
14s
13s
配置后:45s
这里我使用了npm 和 yarn 分别多次启动测试发现时间都不一样。拿我的win(运行内存16g、磁盘1.5g)跑的话有时候竟然高达6位数,烦躁的很!可能电脑配置不行吧,每次起这个项目风扇就起飞了、有时候还会出现卡顿😂 条件允许还是上mac吧,真挺丝滑的。
经过多次测试,我发现开发环境如果也配置一些loader、plugins 后会增加启动时间,得不偿失。 没有上vite是因为项目内容太多了,改造成本太高。新项目的话还是建议直接vite吧,不得不说还是vite开发丝滑呀!
所以我这里开发环境直接不配置任何loader、plugins。然后区分开发环境,加载不同配置文件。
因为项目默认用的是vue-cli-service服务,当执行npm run build
和 npm 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%
本次瘦身之旅,只尝试了这部分内容,总体来说还是有效果的。很多知识仅仅停留在熟悉、了解还不够,最终还是要亲自去实践才能真正学习和掌握。
我相信肯定还有很多优化方案、方向,学无止境,欢迎大家评论区讨论交流。