一、前言
随着现在网站越来越酷炫,各种图片,资源库,动画等等用的越来越多,在用户视觉和功能的提升的同时,性能也成为一个必须考虑的点。有人说“一个网站打开时间超过8s,网民就会流失70%以上。”,这种说法我觉得不是很正确的,除非是非常重要、必须要使用的网站,否则超过5s我基本直接关了,体验太差。所以,用户“忍让”是有极限的,要想把握更多的用户,增强用户体验,性能优化是必不可少的一环。
二、性能优化方案
1. 开启gzip压缩
在通过webpack压缩后的文件往往会很大,比如vendor,经常是好几M以上多的,甚至更大。请求资源过大是影响性能的重大因素。在浏览器的请求头里包含着这样一句话Accept-Encoding:gzip, deflate
,这告诉我们浏览器是可以识别gzip压缩的,使用gzip压缩后的文件将大大减小,很多情况下甚至能压缩70%。对于nginx来说更加简单了,只需要配置:
gzip on;
gzip_types text/xml text/css text/plain text/javascript application/javascript application/x-javascript;
让我们来看下效果:
可以看出,vendor直接从744K压缩到了258K,还是很强大的。
2. 路由按需加载
在vue中,资源按需加载有两个好处,1. 使得app.js更加轻量;2. 只有在请求时才加载对应的资源,而不是打开网站全部加载。具体实现参考我的另一篇博客: 传送门
3. 图片、视频异步加载
可以在文档渲染结束之后再加载图片和视频,例如将图片的src在vue生命周期中的mounted中赋值,或者通过Image对象缓存文件
4. 浏览器缓存
摘抄自:点击打开链接
浏览器分为两种缓存,强缓存与协商缓存(也被称为弱缓存),其中协商缓存不用我们自己配置,下面我们通过连续两次刷新页面来观察一下协商缓存。
Last-Modified: sometime
location ~* \.(css|js)$ {
proxy_set_header Host $host;
proxy_pass http://tomcat_xxx;
expires 7d;
}
location ~* \.(jpg|jpeg|png|gif|webp)$ {
proxy_set_header Host $host;
proxy_pass http://tomcat_xxx;
expires 30d;
}
注意我们这里使用的是tomcat,你可能需要的配置与我这个并不一样,但是这并不关键,我们主要需要的是expires这项配置,他表示了我们希望缓存的时间,我们配置的js与css缓存时间为10天,而图片则缓存30天。一起打开浏览器看一下效果。
from memory cache
表明此时是从内存中直接取出缓存,并没有发送http请求,这对一些图片与我们的依赖包vendor相当有用,我们完全可以给这两个资源设定一个较大的缓存时间,这样当用户访问第一次后,这些资源始终会保持在用户的缓存中,就算我们之后更改了很多我们的业务代码,只要依赖没有更改,用户只用加载一些小的业务代码文件就可以了,对于较大的vendor则依然可以从缓存中获取。
我们可以简要的总结一下浏览器的缓存方式并增加一些注意的点。浏览器会首先检测强缓存,如果命中则直接返回缓存文件,不会发送http请求,如果没有命中则去检查弱缓存,当弱缓存命中时返回304状态码,浏览器依然从缓存中获取资源,如果弱缓存也没有命中则返回200状态码重新加载服务器上的资源。
注意点:
- 强缓存、弱缓存只是名字上的区别并没有什么强弱之分,其实对于一般的浏览器来说刷新就会使你当前请求资源的强缓存失效,因为刷新的时候会请求头中会携带一个
max-age=0或是no-cache
,注意我这里说的当前请求资源指的一般是你页面的html文档,但是对于文档中外链的js与img等,不会因为刷新导致强缓存失效。不过如果你直接请求的是一个js文件,那么刷新后这个js文件强缓存也会失效。 - 既然强缓存不会发起http请求,那么服务器资源有变更的情况怎么办。其实webpack生成的hash码就是帮我们解决这个问题用的,当外链的app.123456.js变成了app.654321.js浏览器自然会重新发起请求,这也提示了我们尽量不要去改变vendor导致vendor的hash变更产生缓存失效的问题。