作者:myprelude@github
原文链接: https://myprelude.github.io
转载请注明出处,保留原文链接和作者信息。
开始
为啥需要http缓存,无非就是减少不必要请求操作达到更快的加载速度、更好的用户体验;在现在用户体验为王的时代,http缓存是我们前端工程师必须知道并掌握的知识点。http缓存分为协商缓存和强缓存,还有一个是浏览器自身的缓存机制。我们打开淘宝网网页(taobao.com)F12(mac:command+option+i)打开network,刷新页面,这时可以查看network里面Size… 如下图:
from memory cache
上图可以看见有的资源在页面刷新后显示from memory cache;from memory cache 表示本次资源加载直接从内存中加载。大家都知道从内存里取东西是最快的,所以from memory cache 加载速度很快,但是不同的浏览器把资源存入内存的规则不一样,经过大量的实验发现base64的图片或者体积很小的js和css会很大概率被放入缓存中。这个缓存的生命周期就是当前tab页面,一旦tab页面关闭存入内存中的资源就会被释放。
强制缓存
强制缓存是指页面加载一次后下次资源(做过强制缓存的资源)就直接从我们硬盘中加载而不需要再次请求接口。点击上图Size显示from disk cache,可以看到Response Header,我们可以看到如下关键字段
....
expires: Thu, 10 Oct 2019 08:11:06 GMT
cache-control: max-age=31536000
...
expires
是告诉我们该资源过期时间,是根据本地时间来判断的。如果本地时间大于这个时间则会重新拉取资源。因为本地时间有可能出现错误就会导致资源不能更新;所以这个在http1.0中渐渐被淘汰了。很多网站还在使用这个是为了做向下兼容。
cache-control
是以毫秒为单位的时间戳;表示改资源将会在这个毫秒过后过期,我需要重新拉取资源。这个就解决expires的问题。它还有如下参数
- no-cache :需要使用对比缓存来验证缓存数据(后面会说)
- no-storg :表示不缓存请求资源,每次都去服务器重新获取。
- max-age :毫秒数,表示多少毫秒后过期。
使用
一帮我们对于公共资源,长期不会发生改变的资源都使用强制缓存。如我们页面的logo图片 公共样式代码 就可以如下设置
expires: Thu, 10 Oct 2020 08:11:06 GMT
cache-control: max-age=31536000
expires和cache-control如果同时存在的话,cache-control的优先级会高于expires。
协商缓存
协商缓存和强制缓存不一样,协商缓存会去请求一次服务器,询问服务器上资源是否发生更新,如果没有发生更新返回告诉浏览器继续使用之前加载的资源,如果发生变更直接返回新资源。浏览器通过以下字段去判断是否更新;
last-modified # If-Modified-Since
last-modified: Tue, 11 Dec 2018 06:04:38 GMT
last-modified 是表示该资源最后一次修改时间,如果服务器返回 If-Modified-Since 也是这个时间就继续使用之前缓存的资源;否则重新拉取资源。由于这个是精确到秒,就会出现对快速更新的资源不能及时察觉。
Etag # If-None-Match
Etag:ahdkafaebk
Etag:是文件发生变更的标识符。If-None-Match返回new的标识符,道理和last-modified相同,但是这个可以监测到每次文件的变动。
使用
cache-control:no-cache
last-modified: Tue, 11 Dec 2018 06:04:38 GMT
// 或
Etag:ahdkafaebk
需要配合cache-control:no-cache一起使用。Etag优先级高于last-modified。
总结
http缓存是需要服务端和客户端一起配合,一个完美缓存策略需要大家的努力,即使你们公司缓存是服务端在做我们也可以给他们提一点我们专业的意见。下面是推荐的缓存策略。