前言
之前做的一个Vue项目,流程大概是这这样的:从公众号进入,由外系统获取用户的openid等信息,然后再跳转到项目首页进行加载初始化操作。
业务最近反应进入首页很慢,于是大致排查了下,由于外系统需要去微信获取用户授权,用户的的openid,调用定位接口获取位置等信息,想着会不会是他们的问题,经过沟通,他们也是按照微信的接口文档进行操作,没有什么优化的空间,于是想着能不能提高我们首页的加载速度,百度一番,果然有相应的优化方法,
主要有以下几个方法:
打包的时候不生成「.map」文件。
打包的时候生成gzip文件,部署的时候,让「nginx」直接读取gzip文件。
路由加载的时候采用「懒加载模式」。
首页较大的图片适当的进行压缩。
三方库采用「CDN」的方式引入。
由于「CDN」的方式改动较多,所以这次优化没有采用该方法,而是采用了其他四种方法,在测试环境上进行测试加载速度提高了一倍,加载时间从4秒减少到2秒,在生产上网络较好应该要快些。下面来依次介绍下这几种方法的具体操作。
分析文件大小
在开始操作具体的优化方法之前,先来分析下哪些代码文件比较大,较大的文件可以进行压缩,使用webpack-bundle-analyzer来进行分析。
首先执行「npm install cross-env --save-dev」安装cross-env依赖。
在package.json文件的scripts下面加上:
"analyze": "cross-env NODE_ENV=production npm_config_report=true npm run build"
如下图所示:
在项目的根目录下执行「npm run analyze」命令,执行之后,在浏览器上会自动打开一个页面,显示项目
具体的文件及大小,如下图:
可以看到,项目中vendor.js文件最大,为184.9 KB,该文件是Vue打包的时候自动生成的;通过该方法可以看到哪些js是我们没有使用的或者可以优化的,如果没有使用可以进行删除。
此外,把鼠标移到某个文件上面,还可以看到提示如果采用gzip压缩后的大小,比如vendor.js提示如果采用gzip进行压缩,压缩后的大小为61.26 KB,文件变小了,加载速度自然就快了嘛。
优化之前
先来看看优化之前的加载耗时情况:
可以看到:
总耗时 4.33 秒。
app.css文件大小为1.1 MB,耗时2.42秒。
vendor.js文件大小为434 KB,耗时1.26秒。
app.js文件大小144 KB,耗时598毫秒。
一张png图片大小347 KB,耗时1.51秒。
到后台查数据的耗时反而很小,225毫秒。
开始优化
接下来,开始按照文章开篇的办法进行操作。
方法一:不生成 .map 文件
一般我们上生产的代码都会经过压缩,去空格,babel编译转化。然而压缩转化之后的代码和源代码之间的差异很大,当出现问题的时候会造成无法 DEBUG的问题,而编译后的.map文件主要是我们用来进行错误定位的。
了解了.map文件作用之后,我们在本地开发测试的时候可以使用.map来进行调试,上生产了之后,bug基本修改完毕,所以在编译打包的时候可以不生成.map文件。
在编译打包的时候,.map文件的生成是由config/index.js文件的「productionSourceMap」属性来控制的,为true的时候,会生成.map文件,为false的时候,不会生成.map文件,默认为true。
所以我们把该属性设置为false,编译打包的时候就不会生成.map文件了。
方法二:采用 gzip 压缩
还记得在文章开篇提到的用webpack-bundle-analyzer来分析文件大小吗,把鼠标移到某个文件上面,会提示现在文件的大小是多少,gzip压缩之后文件的大小,
要想进行gzip压缩,首先在编译打包的时候,要生成.gz文件,然后nginx配置需要把gzip模式打开,访问项目的时候,自动会找到.gz的文件.
首先安装压缩插件,在项目根目录下执行如下命令安装:
npm install --save-dev compression-webpack-plugin
然后把config/index.js文件的「productionGzip」属性设置为true。
图片中注释也写清楚了,设置为true之前先执行上述命令安装插件。
把build/webpack.prod.conf.js文件中的asset改为filename:
经过上面一系列操作之后,执行npm run build命令打包,此时在 dist 下会生成很多的.gz文件,会比压缩之前的文件小了很多。
4. 现在生成了.gz文件之后,还需要配置nginx开启gzip 模块,访问项目的时候,自动会找到 .gz 的文件。nginx 配置如下:
http{
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 8;
gzip_buffers 16 8k;
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;
}
「======有坑=======」
这里有一点要注意,安装compression-webpack-plugin插件之前,先到package.json文件中看下你项目的webpack的版本是多少,目前最新版需要运行在webpack4.0以上,如果你的webpack的版本号是3.x的,则安装compression-webpack-plugin的时候,需要安装1.x的版本。
我之前也是直接执行上面的命令安装,这样安装的是最新的版本,最新版本则要求webpack的版本在 4.0 以上,而我的webpack则是 3.6 的,所以我卸载了再重新指定安装了1.1.12版本的。命令如下:
npm install --save-dev [email protected]
方法三:路由采用懒加载模式
路由的懒加载模式可以解决首次加载资源过多导致的速度缓慢问题:vue-router支持WebPack内置的异步模块加载系统。所以,那些使用较少的路由组件不必打包进bundles里,只需要在路由被访问时按需加载即可。
之前项目上采用的是非懒加载模式,即如下写法:
import Vue from "vue"
import Router from "vue-router"
import index from "@/views/index"
import userList from "@/views/userList"
Vue.use(Router);
export default new Router({
routes: [
{
path: "/",
name: "index",
component: index
},
{
path: "/c",
name: "chargeTypeList",
component: userList
}
]
})
优化的时候,把它改为赖加载模式,即如下写法:
import Vue from "vue"
import Router from "vue-router"
Vue.use(Router);
export default new Router({
routes: [
{
path: "/",
name: "index",
component: resolve => require(["@/views/index"], resolve)
},{
path: "/c",
name: "chargeTypeList",
component: resolve => require(["@/views/userList"], resolve)
}
]
})
方法四:较大图片进行压缩
在文章开头说的优化之前的加载耗时中,有张图片是png格式的,大小为347 KB,耗时1.51秒:
优化的办法就是进行图片的压缩,改为jpg的,大小为199 KB,最后耗时241毫秒。
总结
通过上述的几个方法优化之后,首页的加载耗时情况如下所示:
可以看到:
总耗时1.75秒。
app.css文件大小为300 KB,耗时887毫秒。
vendor.js文件大小为131 KB,耗时610毫秒。
app.js文件大小30.7 KB,耗时342毫秒。
图片大小119 KB,耗时241毫秒。
在测试环境上多次测试后,平均下来,首页的加载速度从4秒左右提高到2秒左右。
「完」
本文首发于个人公众号【Java技术大杂烩】,欢迎关注转载。