浅谈前端性能优化(缓存篇)

今天看到一篇文章谈的是浏览器的缓存,正好也想来聊聊前端对性能的优化。

关于浏览器缓存

首先想聊一下浏览器缓存的机制,主要是两种强缓存和协商缓存

1.强缓存:不会向服务器发送请求,直接从缓存中读取资源,在chrome控制台的network选项中可以看到该请求返回200的状态码,并且size显示from disk cache或from memory cache;

2.协商缓存:向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源;

两者的共同点是,都是从客户端缓存中读取资源;区别是强缓存不会发请求,协商缓存会发请求。

强缓存

Expires是HTTP/1.0控制网页缓存的字段,可由服务端通过配置Nginx来直接设置。如果客户端的时间小于设置的时间则默认缓存不需要更新直接使用浏览器缓存。
但是Expires有个很严重的不足就是对比的时间是客户端本地的时间这样就会造成如果客户端的时间不正确的话则设置了Expires也毫无意义。

Cache-Control是HTTP/1.1用来控制网页缓存的。具体可直接设置秒数,当设置为max-age=300时浏览器在5分钟之内请求则会被强制使用缓存。Expires与Cache-Control的作用都差不多但是由Cache-Control是HTTP/1.1的所以在都设置的情况下Cache-Control的优先级会高于Expires。

协商缓存

协商缓存中比较常见的是对比缓存。对比缓存就是客户端请求资源的时候先访问浏览器的缓存拿到缓存的标识,然后携带该标识发送HTTP请求。若无资源更新则返回304客户端直接从缓存中读取。如果是资源更新了的情况下则服务器直接返回资源200,客户端则将新的资源存入缓存。

在现代的浏览器中拥有一下两种的方式:

浏览器缓存过程

首先一个从未加载过资源的客户端第一次加载资源,服务器返回200,浏览器将返回的资源下载并且存入缓存。并且把response header以及该请求的时间一并缓存。

下一次加载的时候会以此根据客户端当前的时间对比Cache-Control 和 Expires 如果时间没过期则命中强缓存,客户端不发送请求并且直接在本地缓存中拉取结果。

或者在服务端收到请求后先根据Etag的值判断资源有无经过修改,如果没有则命中协商缓存,返回304客户端直接从缓存中读取资源。

用户行为对浏览器缓存的控制

地址栏访问,链接跳转是正常用户行为,将会触发浏览器缓存机制;

F5刷新,浏览器会设置max-age=0,跳过强缓存判断,会进行协商缓存判断;

ctrl+F5刷新,跳过强缓存和协商缓存,直接从服务器拉取资源。

避免浏览器缓存

事实上有很多的业务场景是不需要任何的缓存的,除了浏览器设置的隐私模式,也可以设置请求头:

1
Cache-Control: no-cache, no-store, must-revalidate .

或者直接用打包后生成带hash的资源。HTML也可以控制浏览器不缓存:

1
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"/>

总结

首先强制缓存优先协商缓存进行,若强制缓存生效则直接使用强制缓存,若不生效则进行协商缓存。协商缓存由服务端直接决定是否使用缓存。若协商缓存失效则代表缓存失效,需要重新请求获取结果。

hi you can see me