Vue包大小优化的实现(从1.72M到94K)


Posted in Vue.js onFebruary 18, 2021

一、背景

最近做了一个网站,uidea,是用来辅助独立开发者做一些 UI 设计的,当时只管开发,等部署完以后,发现访问速度堪忧
毕竟是个小水管服务器,相比提高带宽,还是先看看代码上能不能优化一下,性价比更高
这个是优化前的包大小,这家伙都上 1.72 M 了,小水管加载时间直接往 3s 以上走了,臣妾扛不住啊

Vue包大小优化的实现(从1.72M到94K)

二、目标

这必须得优化一下,优化前得大致定一下目标,目标又需要指标来衡量,所以定了两个指标:

  • 页面加载时间不多说,至少得 1s 以内,越快越好
  • 包大小控制在 200k 以内

为什么定这两个目标呢?首先页面加载时间是最终要解决的问题,那页面加载时间初步来看,影响因素有两个,网络和包大小,网络暂时缺钱没法升级,所以主要优化就集中在包大小上
首先要定义什么是包大小,我这里主要指入口包大小,对应 Vue 就是 app.js 和 app.css,入口加载完页面至少可以展示了

那包大小要优化到什么程度呢?

一方面 vue-cli-service 建议不超过 244K,另一方面就是找对标,看看类似的网站包大小多少,那我们也有个参照,我选择的是 materialpalette,看了下他的包大小大概在 150k 左右,我的功能更复杂一些,所以取了两者中间的 200K 作为目标

这里为什么要讲目标呢?因为目标其实是很重要的,老话也说有的放矢,没有目标,那执行的过程中很容易半途而废,或者只前进半步就终止了

拿谈恋爱来说,如果你的目标是找个女朋友,那大概率找不到,但是如果你的目标是追到某个确定的女生(比如张三)做女朋友,那成功的概率就大大增加了,因为你可以去针对这个女生去做针对性的准备

三、方案

目标定了,然后就是定方案

虽然咱第一次做 Web 的优化,但是之前有过安卓包大小优化的经验呀,道理总是相通的,所以第一时间想了下面几个策略

  1. 代码混淆
  2. 资源放到 cdn,因为开发的时候图省事,资源放在 assets 下面,直接 require 引入了,这也是一个大头
  3. 无用库删除,功能相近的库合并,只用到少部分功能的库,看看能否自己实现
  4. gzip 压缩
  5. 第三方库也放到 cdn

1 - 3 三个优化方案是首先想到的,然后网上搜了下 Vue 对应的优化策略,又增加了后面两个
还有一些其他方案,比如路由懒加载,但是因为这个网站主要内容都集中在首页,所以这个就没考虑了(好东西虽多,但因地制宜最好)
所以一共定了 5 个优化策略,下面就开干

四、执行

1. 代码混淆

代码混淆就不多说了,一方面节省包大小,一方面还能增加一些反编译的难度,直接网上搜了 Vue 混淆配置(毕竟要站在巨人肩膀上),试了下确实好使,配置如下

const CompressionWebpackPlugin = require('compression-webpack-plugin');
module.exports = {
 configureWebpack: (config) => {
  // 引入uglifyjs-webpack-plugin
  let UglifyPlugin = require('uglifyjs-webpack-plugin');

  if (process.env.NODE_ENV == 'production') {
   // 压缩混淆
   config.mode = 'production'
   // 将每个依赖包打包成单独的js文件
   let optimization = {
    minimizer: [new UglifyPlugin({
     uglifyOptions: {
      warnings: false,
      compress: {
       drop_console: true,
       drop_debugger: false,
       pure_funcs: ['console.log']
      }
     }
    })]
   }
   Object.assign(config, {
    optimization
   })
  } else {
   // 为开发环境修改配置
   config.mode = 'development'
}
  }
 }
}

2. 资源放到 cdn

这一步也容易做,资源全部都放到阿里云 oss 上,几分钟搞定

3. 无用库删除

这一步花了不少时间,因为开发的时候图省事,很多库直接 github 上一搜,yarn add 引入就完事了,现在需要细细的再拆分一下

在打包命令后面加 --report 看一下打包的状态

yarn build --report

Vue包大小优化的实现(从1.72M到94K)

首先是去掉 ElementUi(gzip 压缩后大约 158k),开发的时候 ElementUi 和 Vuetify 混用了,其实只留一个 Vuetify 就够了,然后对界面做一些小小的改造就完成了

然后是 lodash,只用到了其中几个方法,但是他的整个体积不小,gzip 压缩后大概 25k,于是找了 lodash 源码,打算把用到的几个方法抽出来,但是 lodash 代码嵌套、引用太深了,不太抽,干脆直接干掉这个库,找了几个更纯粹的实现做了替换,主要时间花在了读 lodash 源码上

再然后就是 vuescroll,在实现滚动条样式自定义的时候,偷懒直接用了这个库,发现这个库体积还是不小的,gzip 压缩后将近 20k,直接干掉,自己写一下样式吧(这件事告诉我们,现在偷的懒,以后会以别的方式还回来的 0_0)
这样就干掉了几个大头库

4. gzip 压缩

这个是网上找的解决方案,直接在 vue.config.js 里加点配置,然后 nginx 里也需要做一下对应的配置

// vue.config.js
module.exports = {
 configureWebpack: (config) => {
  if (process.env.NODE_ENV == 'production') {
   // ...
   // gzip
   config.plugins.push(new CompressionWebpackPlugin({
    algorithm: 'gzip',
    test: /\.js$|\.html$|\.json$|\.css/,
    threshold: 10240,
    minRatio: 0.8
   }))
  }
  // ...
 }
}
// nginx 直接开启下面的配置
gzip_static on;

这样打包以后,会生成 .gz 文件,nginx 会自动使用 .gz 文件

5. 第三方库放到 cdn

这里主要是处理 Vuetify 这个库,毕竟 gzip 以后也有将近 50k 的大小,放到 cdn 上会快一些
首先是打包配置中去掉 Vuetify

module.exports = {
 // ...
 configureWebpack: (config) => {
  if (process.env.NODE_ENV == 'production') {
   // 第三方库不打包,使用 cdn
   config.externals = {
    vuetify: 'Vuetify'
   }
  } else {
   // 为开发环境修改配置
   config.mode = 'development'
   config.externals = {
    vuetify: 'Vuetify'
   }
  }
 }
}

然后在 index.html 里手动加载 vuetify css 和 js

<link href="https://cdn.staticfile.org/vuetify/2.4.4/vuetify.min.css" rel="external nofollow" rel="stylesheet">
<script src="https://cdn.staticfile.org/vuetify/2.4.4/vuetify.min.js"></script>

这里其实有一些更好的方式,可以通过 webpack 参数传给 index.html,通过 ejs 引入,现在比较简单,这里就没做了

五、效果

通过上面几个策略,最终包大小从 1.72 M 优化到 94k

Vue包大小优化的实现(从1.72M到94K)

六、后续

总体看来,优化效果是明显的,但是还有后续可以做的事情:

  • 更精细化优化,应该可以结合 webpack 做更深的定制化
  • 对上面说到的 cdn 上的第三方库做整合,毕竟直接放在 index.html 里太散,并不是很好的项目结构,也不利于后面开发
  • 对后续的代码开发做规范,比如三方库引用的规范、资源的引入规范等等,可以做的事情还是很多的
  • 每次部署前的性能测试,主要看看页面加载速度是否达标

可以做的事情还很多,有时候做一件事,达成目标并没有结束,维持目标也是需要考虑的

到此这篇关于Vue包大小优化的实现(从1.72M到94K)的文章就介绍到这了,更多相关Vue包大小优化内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
Vue+element-ui添加自定义右键菜单的方法示例
Dec 08 Vue.js
Vue 组件注册全解析
Dec 17 Vue.js
vue 在单页面应用里使用二级套嵌路由
Dec 19 Vue.js
vue浏览器返回监听的具体步骤
Feb 03 Vue.js
Vue中避免滥用this去读取data中数据
Mar 02 Vue.js
如何使用vue3打造一个物料库
May 08 Vue.js
深入理解Vue的数据响应式
May 15 Vue.js
vue-element-admin项目导入和导出的实现
May 21 Vue.js
vue 实现上传组件
May 31 Vue.js
Vue实现跑马灯样式文字横向滚动
Nov 23 Vue.js
vue+echarts实现多条折线图
Mar 21 Vue.js
vue实力踩坑之push当前页无效
Apr 10 Vue.js
Vue如何实现变量表达式选择器
Feb 18 #Vue.js
WebStorm无法正确识别Vue3组合式API的解决方案
Feb 18 #Vue.js
如何在 Vue 中使用 JSX
Feb 14 #Vue.js
Vue单页面应用中实现Markdown渲染
Feb 14 #Vue.js
vue仿携程轮播图效果(滑动轮播,下方高度自适应)
Feb 11 #Vue.js
Vue+Bootstrap实现简易学生管理系统
Feb 09 #Vue.js
详解Vue的七种传值方式
Feb 08 #Vue.js
You might like
改进的IP计数器
2006/10/09 PHP
Codeigniter+PHPExcel实现导出数据到Excel文件
2014/06/12 PHP
Yii使用migrate命令执行sql语句的方法
2016/03/15 PHP
Laravel (Lumen) 解决JWT-Auth刷新token的问题
2019/10/24 PHP
用javascript实现兼容IE7的类库 IE7_0_9.zip提供下载
2007/08/08 Javascript
jquery实现表格奇数偶数行不同样式(有图为证及实现代码)
2013/01/23 Javascript
关于javascript模块加载技术的一些思考
2014/11/28 Javascript
js行号显示的文本框实现效果(兼容多种浏览器 )
2015/10/23 Javascript
Select下拉框模糊查询功能实现代码
2016/07/22 Javascript
Bootstrap Table服务器分页与在线编辑应用总结
2016/08/08 Javascript
利用JQUERY实现多个AJAX请求等待的实例
2017/12/14 jQuery
基于js 各种排序方法和sort方法的区别(详解)
2018/01/03 Javascript
Nuxt.js开启SSR渲染的教程详解
2018/11/30 Javascript
解决vue-router路由拦截造成死循环问题
2020/08/05 Javascript
[01:02:25]2014 DOTA2华西杯精英邀请赛5 24 NewBee VS VG
2014/05/25 DOTA
[35:26]DOTA2上海特级锦标赛B组小组赛#2 VG VS Fnatic第三局
2016/02/26 DOTA
[00:36]我的中国心——Serenity vs Fnatic
2018/08/21 DOTA
python中from module import * 的一个坑
2014/07/20 Python
tensorflow学习笔记之mnist的卷积神经网络实例
2018/04/15 Python
实时获取Python的print输出流方法
2019/01/07 Python
django之使用celery-把耗时程序放到celery里面执行的方法
2019/07/12 Python
通过 Django Pagination 实现简单分页功能
2019/11/11 Python
利用python对excel中一列的时间数据更改格式操作
2020/07/14 Python
python利用xpath爬取网上数据并存储到django模型中
2021/02/26 Python
澳大利亚领先的在线葡萄酒零售商:Get Wines Direct
2018/03/27 全球购物
小学生考试获奖感言
2014/01/30 职场文书
《忆江南》教学反思
2014/04/07 职场文书
寄语是什么意思
2014/04/10 职场文书
2014年话务员工作总结
2014/11/19 职场文书
2014幼儿园教育教学工作总结
2014/12/17 职场文书
2015年教师党员公开承诺书
2015/01/22 职场文书
大学推普周活动总结
2015/05/07 职场文书
小学主题班会教案
2015/08/17 职场文书
2019个人工作计划书的格式及范文!
2019/07/04 职场文书
浅谈Python中的函数(def)及参数传递操作
2021/05/25 Python
分析ZooKeeper分布式锁的实现
2021/06/30 Java/Android