最近项目完结,上线。浏览器在没有缓存的情况下首次加载时间十多秒钟,出现很长的白屏时间,这在当今互联网时代我觉得是不可忍受的,带来的用户流失我觉得也不容忽视。
分析vue的机制可以知道,vue是把所有的js,cs打包成精简的几个js和css文件然后进行压缩处理,我的工程中是用webpack进行打包的,打包后依赖vue,element,lodash等被打包压缩成了vendor.0e7e218fb4893ccef482.js,而自己的一些js则被编译成了app.e2bb24ea4231ba75dc67.js,浏览器会在这些文件都请求完成之后再解析这些文件,页面的跳转这些都会在前端通过浏览器自主完成,完全不依赖后台,和后台的唯一交互就是ajax的数据curd,这样就完成了前后的完全分离
回到正题,我的项目在用vue-cli build之后部署,在chrome查看发现vendor很庞大:
app.js大小:
总大小:
可以发现总加载时间为16.22s,DOMContentLoaded时间为15.34s,浏览器开始解析dom到解析完成, 1s不到,所有的时间都卡在了请求资源的路上。
所以开始茫茫优化之路:
1.添加loading动画
这算是一剂治标不治本的药,没有减少加载时间,但是会在白屏的时候给一个加载动画,告诉用户:‘你的浏览器没有卡住,正在拼命加载资源,请耐心等候而已’。
index.html
<style>
body {
background-color: #f6f8f9;
}
#Loading {
top: 50%;
left: 50%;
position: absolute;
-webkit-transform: translateY(-50%) translateX(-50%);
transform: translateY(-50%) translateX(-50%);
z-index: 100;
}
@-webkit-keyframes ball-beat {
50% {
opacity: 0.2;
-webkit-transform: scale(0.75);
transform: scale(0.75);
}
100% {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(1);
}
}
@keyframes ball-beat {
50% {
opacity: 0.2;
-webkit-transform: scale(0.75);
transform: scale(0.75);
}
100% {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(1);
}
}
.ball-beat > div {
background-color: #279fcf;
width: 15px;
height: 15px;
border-radius: 100% !important;
margin: 2px;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
display: inline-block;
-webkit-animation: ball-beat 0.7s 0s infinite linear;
animation: ball-beat 0.7s 0s infinite linear;
}
.ball-beat > div:nth-child(2n-1) {
-webkit-animation-delay: 0.35s !important;
animation-delay: 0.35s !important;
}
</style>
...
<div id="Loading">
<div class="loader-inner ball-beat">
<div></div>
<div></div>
<div></div>
</div>
</div>
<div id="app"></div>
...
App.vue
created() {
document.body.removeChild(document.getElementById('Loading'))
},
代码很简单,在vue没有加载的时候初始化一个动画,在app.vue加载完成的时候一处加载动画,至于动画的样式和设计,可以自由发挥
2.懒加载
所谓懒加载就是在路由中动刀子,需要某个页面的时候再去服务器加载:
...
{
//系统主页
path:"/home",
component: resolve => require(['@/views/Home'], resolve),
name:"homeLink"
},
...
chrome中查看结果,加载该页面的时候去服务器请求:
通过如上改造,可以优化app.js的大小
3.cdn引入第三方模块:
...
<body :style="{background-color:bodyColor}">
<div id="Loading">
<div class="loader-inner ball-beat">
<div></div>
<div></div>
<div></div>
</div>
</div>
<div id="app"></div>
<script src="https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/element-ui/2.4.0/index.js"></script>
</body>
...
将比较大的包通过scprit外联的方式引入,不打包到vendor中,减少vendor的体积,也减少自身服务器的压力,在main.js中去掉相关的import,避免被打包
chrome中查看cdn缓存的大小和相关文件如下:
4.nginx配置gzip压缩
在nginx中采用压缩可以有效减小传输的大小,对于我这个前端来说nginx还是很有意思的东西,值得研究,自己打架服务器,用nginx也很轻量,打开nginx配置文件,nginx.conf:
nginx.conf
#打开gzip,并进行相关参数设置,具体查询文档
gzip on;
gzip_min_length 1k;
gzip_buffers 4 8k;
gzip_http_version 1.0;
gzip_comp_level 8;
gzip_proxied any;
gzip_types application/javascript text/css image/gif;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
5.服务端渲染
服务端渲染是一个比较大的课题,涉及的东西比较多,自己也没有实际的实践经验,后续实践后再补上,能确定的就是如果自己的网站需要seo,需要被爬虫爬取的话,就可以尝试下服务端渲染。但是服务端渲染涉及工程代码改造,尤其是在当前工程代码已经成型,测试也已经完成的情况下再进行改造,付出的成本和不可预知的错误,是需要反复斟酌的。
但是对服务端的探索还是必须的,作为一个合格的前端,这是必须探索的一个领域