2021-01-01 18:55:30
浏览器缓存概述
浏览器缓存是前端性能优化的重要手段,通过本地保存远端资源,减少网络IO消耗,提高访问速度。浏览器缓存包含多种类型,如HTTP缓存、indexDB、cookie、localstorage等,其中HTTP缓存是最常用的类型。
缓存类型
第一次请求数据
当浏览器第一次请求数据时,由于缓存中没有对应的缓存数据,因此需要向服务器发送请求。服务器返回数据后,浏览器会将数据存储至缓存数据库中。

强制缓存
强制缓存是指用户请求数据时,如果命中强缓存,则不向服务器请求,而直接从本地资源获取,返回200状态码,并提示from disk cache或from memory cache。强制缓存的response header中会有Expires或Cache-Control字段来表明失效规则。
Expires:Expires的值为服务端返回的到期时间,但存在时间误差和HTTP版本兼容性问题,因此HTTP 1.1版本推荐使用Cache-Control。
Cache-Control:Cache-Control是最重要的规则,常见的取值有private、public、no-cache、max-age等。Cache-Control的优先级高于Expires,且功能更为强大。

协商缓存
协商缓存是指用户请求资源时,浏览器直接向服务器发送请求,协商对比服务端和本地的资源,验证本地资源是否失效。协商缓存一般使用If-Modified-Since/Last-Modified和If-None-Match/Etag。
Last-Modified / If-Modified-Since:Last-Modified是服务器响应请求时告诉浏览器资源最后的修改时间,If-Modified-Since是浏览器再次请求资源时通知服务器上次请求时资源的最后修改时间。
If-None-Match / Etag:Etag是服务器响应请求时告诉浏览器当前资源在浏览器的唯一标识,If-None-Match是再次请求服务器时通知服务器客户端缓存数据的唯一标识。
Etag在精确度和优先级上优于Last-Modified,但在性能上略差。

强制缓存和协商缓存的关系
强制缓存和协商缓存命中缓存资源后,都是从本地读取资源。强制缓存优先级高于协商缓存,如果强制缓存生效,则直接使用缓存,不再执行协商缓存规则。如果强制缓存规则不生效,则需要进行协商缓存判断。
缓存相关header
强制缓存
强制缓存的response header中会有Expires或Cache-Control字段。Expires由于存在时间误差和HTTP版本兼容性问题,推荐使用Cache-Control。Cache-Control的常见取值有private、public、no-cache、max-age等,其中max-age表示缓存的有效时间。

协商缓存
协商缓存的request header中会有If-Modified-Since或If-None-Match字段,response header中会有Last-Modified或Etag字段。服务器会根据这些字段判断客户端缓存的资源是否有效。
缓存请求流程
浏览器缓存的请求流程如下:

实例分析
以华为云官网为例,分析不同部件的缓存策略:
官网首页
Html:缓存有效时间为0s,每次加载页面都需要重新向源服务器获取资源。
Css、Js、Image:允许使用本地缓存,且存在强制缓存时间(按需设置)。强制缓存失效后再进行协商缓存。
Gif:使用no-cache,不允许缓存,强制每次向源服务器确认数据。

社区
Html:缓存权限为public,本地缓存永远到期,每次加载页面都需要重新向源服务器获取资源。
Css、Js:允许使用本地缓存,强制缓存时间为1天;强制缓存失效后再进行协商缓存。
Image:png格式文件强制缓存时间为1周,jpg格式文件为1月;强制缓存失效后再进行协商缓存。

云市场、个人中心、论坛
Css、Js、Image:强制缓存时间为1天或1周(不同文件不同);强制缓存失效后再进行协商缓存。



总结
在现网页面中,css、js、image等不同类型文件的缓存策略大致相同,即同时存在强缓存和协商缓存策略。对于强缓存,给定本地缓存的有效时间max-age;对于协商缓存,给定Last-Modified和Etag标识。同时,部分文件会存在特殊的缓存设置,如添加版本号强制刷新缓存等。通过合理的缓存策略,可以提升页面加载速度,同时确保页面的准确性。