vue项目性能优化

一、 使用webpack-bundle-analyzer 分析打包后的生成的文件结构进行优化;

在package.json配置 "analyz": "NODE_ENV=production npm_config_report=true npm run build" ,然后运行 npm run analyz 即可;

image.png
image.png

通过分析图,可以查看哪些有重复的文件或者哪个文件较大从而相应的进行优化;

这里提一下,左上角的stat、parsed及gzip表示什么意思:
stat表示文件的输入大小,parsed表示文件的输出大小,gzip表示通过gzip压缩运行解析的包/模块的大小;https://github.com/webpack-contrib/webpack-bundle-analyzer#size-definitions
这三个状态文件体积相差很大,可见使用gzip的重要性。

二、启用 gzip压缩;

1、安装 compression-webpack-plugin

npm install compression-webpack-plugin --save-dev
这里有个坑,就是如果你的vue版本为2.5.2 及以下 webpack版本为3.6.0及以下时,建议安装compression-webpack-plugin的版本为1.0.0-beta.1 而不是2.0.0,否则可能打包时会报

ValidationError: Compression Plugin Invalid Options

options should NOT have additional properties
2、将vue项目中的 config/index.js中productionGzip: false改为 productionGzip: true;

打包后,可以看到.gz后缀文件了:


image.png
3、然后后台开启gzip模式:

开启 nginx gzip ,在 nginx.conf 配置文件中 配置

http {  //在 http中配置如下代码,
  
   gzip on;
   gzip_disable "msie6"; 
   gzip_vary on; 
   gzip_proxied any;
   gzip_comp_level 8; #压缩级别
   gzip_buffers 16 8k;
   #gzip_http_version 1.1;
   gzip_min_length 100; #不压缩临界值
   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;
 }

保存退出 ,并 重启 nginx

 systemctl reload nginx.service  
 systemctl restart nginx.service
4、测试访问

a、未开启gzip的情况


未开启gzip的情况
未开启gzip的体积

b、开启gzip的情况


开启了gzip的情况

开启了gzip的体积

可以看到 开启后响应头里有 content-encoding: gzip,且体积减少了一半还多。

三、解决vendor.js体积过大的问题

上面我们可以看到未经过gzip压缩,vendor.js体积有730kb,体积挺大的,vendor.js是第三方库经webpack打包而生成的集合;如下面的main.js 引用的第三方库ElementUI 、axios会被打包在vendor.js中


image.png

其实 我们可以使用cdn来引入第三方库:

1、选用cdn服务商

如 选用unpkg来作为第三方提供 https://unpkg.com 或者 https://www.bootcdn.cn/ 如我想要axios包则输入网址为 https://unpkg.com/axios/ (末尾加斜杠代表你要查询该库的所有版本列表)

2、在index.html中将你所需的第三方库的链接加入即可:

我以axios为例:


image.png

注:应该加入到<div id="app"></div>前面

3、启用DNS预解析

在index.html的header中加入

  <meta http-equiv="x-dns-prefetch-control" content="on">
  <link rel="dns-prefetch" href="cdn域名">
  <meta http-equiv="x-dns-prefetch-control" content="on">
  <link rel="dns-prefetch" href="https://cdn.bootcss.com">
4、webpack.base.conf 中添加 externals 来告诉webpack我们这些第三方库不需要打包
image.png
  externals:{
    "axios":"axios"  // key--axios 为你在项目中使用的名字,value--axios 为axios库的模块名为axios
  },

库的模块名可以在源码中看,如element-ui 则为ELEMENT


image.png
5、去除原有的引用

包括 import axios from 'axios';Vue.use(axios )
,当然如果为了避免去除import axios from 'axios';后导致很多eslint 警告,你可以保留import axios from 'axios';; 参考依据: 外部扩展(externals)

https://webpack.js.org/configuration/externals/

完成后打包一下观察vendor.js的体积变化:

未使用cdn的情况
使用cdn以后

可以看到vendor.js减少了12kb;也就是axios.min.js的大小。这里其实还可以将vue、element ui 都拎出来,可以减少很多体积;

题外话:

a、app.js
app.js 入口文件打包的结果,里面将项目中的api接口名及请求和响应等拦截器、路由组件关系等文件全部压缩打包了,大部分为我们自己编写的代码

b、manifest.js
manifest.js 模块化的应用程序的所有代码,里面是 建立hash映射关系的文件


image.png

c、vendor.js 第三方库,一般是node_modules里面的依赖进行打包

d、vendor-async.js
vue中mixin里的所有代码都会打包至vendor-async.js中

四、采用webpack.DllReferencePlugin将不常变更的库免二次打包编译;

这个可大大减少编译时间,同时可使用未变更的文件的缓存;
具体可参考
1、 Webpack的dll功能
2、webpack进阶——DllPlugin优化打包性能(基于vue-cli)

其实采用webpack.DllReferencePlugin跟上面介绍的--解决vendor体积过大的问题中的 externals方法存在异曲同工之处,貌似它们间有差别,但这个差别有待考证:


image.png

经过查看的回答发现webpack.DllReferencePlugin可以由autodll-webpack-plugin完美替代,这点待后面有时间再研究;

五、路由懒加载

使用

// 官方写法
const CardActConsume = () => import('@/components/club/CardActConsume')
// 自己的写法
const CardBuyConsume = (resolve) => {
  import('@/components/club/CardBuyConsume').then((module) => {
    resolve(module)
   });
 }
...
    {
          path: '/club/:id/cardactconsume',
          name: 'clubcardactconsume',
          component: CardActConsume,
   }
...


替代原有的

import CardActConsume from '@/components/club/CardBuyConsume'

这个就不多说了 ,可见官方文档: https://router.vuejs.org/zh/guide/advanced/lazy-loading.html#%E6%8A%8A%E7%BB%84%E4%BB%B6%E6%8C%89%E7%BB%84%E5%88%86%E5%9D%97;另外可以把组件按组分块打包成一个js:

image.png

六、webpack 配置文件记得区分开发环境和生产环境

生产环境不要包含HotModuleReplacementPlugin 等没有必要的插件;

七、提升服务器带宽

如果条件运行,跟运维说下让其提升web页面的带宽。ps:如果带宽为1M/s,说明太带宽设置的太小了,可以设置5M/s及以上。ps:我们是10M/s

八、如果使用了cdn,可以参考购买的cdn服务商的说明

这里以阿里云为例:
1、性能优化概述
2、提高CDN缓存命中率

九、推荐文章集合

https://web.dev/fast/

推荐资料:
1、https://webpack.docschina.org/guides/lazy-loading/
2、 vue-cli中的webpack配置

参考资料:
1、完美解决 vue webpack 单页面 加载慢 gzip 访问 vendor.js 打包文件过大问题
2、 使用vue-cli生成的vendor.js文件太大,有办法减少体积吗?
3、[https://juejin.im/post/5a291092518825293b50366d#heading-2](VueSPA 首屏加载优化实践)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容