Open diveDylan opened 4 years ago
作为面试高频面试题,一直通过博客去了解这个概念总是似懂非懂。我们知道的缓存有本地缓存浏览器缓存,浏览器缓存其实有两种方式,常用的http1缓存还有service worker策略缓存,本文主要介绍http缓存
什么是缓存?
缓存是一种保存资源副本并在下次请求时直接使用该副本的技术
什么是http cache
通过复用以前获取的资源,可以显着提高网站和应用程序的性能。Web 缓存减少了等待时间和网络流量,因此减少了显示资源表示形式所需的时间。通过使用 HTTP缓存,变得更加响应性。当 web 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝,而不会去源服务器重新下载。这样带来的好处有:缓解服务器端压力,提升性能(获取资源的耗时更短了)。对于网站来说,缓存是达到高性能的重要组成部分
拷贝
http cache通过web cache内置对象对Request、Response进行缓存,更多关于Cache对象的内容,值得一提的是Cache也可以作为Service Worker生命周期的一部分。
http cache
web cache
Request
Response
Cache
Service Worker
MDN中将缓存大致分为两大类,私有缓存和共享缓存,你肯定联想到了cache-control的两个策略,这个我们稍后也会聊到这一点。其他缓存类型你也一定不会陌生,CDN缓存、网关缓存、反向代理缓存等。
cache-control
缓存虽然不是必须的,但是重用缓存对于前端的交互提升还是巨大的。 缓存一般作用于GET请求,对其他请求一般无能为力,在service worker中这条可以忽略
GET
cache-control是http1.1控制缓存机制的一个重要header头,有以下几种形式: 1、 no-store 不使用缓存机制,客户端每次都会重新请求服务器资源 2、no-cache使用缓存,每次需要跟服务器确认是否需要,具体是否是用缓存根据客户端和服务端协议决定,也是通常所说的协商缓存,往往需要搭配其他header头使用ETag、Last-Modified等 3、public 指令表示该响应可以被任何中间人(比如cdn,网关)缓存 4、private则表示该响应是专用于某单个用户的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中
http1.1
header
no-store
no-cache
ETag
Last-Modified
public
private
过期时间
过期时间有两种设置方式,两种方式代表的过期时间计算模式也完全不一致。 max-age代表从上次更新到下次需要更新的最大缓存时间 expires是根据指定http-date判断是否是用缓存
max-age
expires
http-date
下图是第一次请求后响应设置expires后,第二次请求内容显示from disk即来自cache
from disk
cache
### deno Drash // max-age this.response.headers.set('cache-control', 'max-age=31536000') // expires this.response.headers.set('expires', new Date(Date.now() + 60000).toUTCString()) // http cache get method fetch('http://localhost:8080/user/1') fetch('http://localhost:8080/user/2') not cache
不同get请求将不会缓存,这也是 revving (不频繁更新的文件会使用特定的命名方式:在URL后面(通常是文件名后面)会加上版本号。)来更新资源的实现。改方案也常用于现代打包工具。
Pragma头 Pragma 是HTTP/1.0标准中定义的一个header属性,请求中包含Pragma的效果跟在头信息中定义Cache-Control: no-cache相同,但是HTTP的响应头没有明确定义这个属性,所以它不能拿来完全替代HTTP/1.1中定义的Cache-control头。通常定义Pragma以向后兼容基于HTTP/1.0的客户端。
Pragma
ETag和LastModified客户端将响应中的这两个的值转为请求中If-None-Match和If-Modified-Since两个值,并传给服务器,没有优先级之分
LastModified
If-None-Match
If-Modified-Since
---> 1、 Req ---> 2、Res Headers{ ETag: 'a', LastModified: 'b'} ---> 3、Req Headers { `If-None-Match`: 'a', `If-Modified-Since`: b} ---> 4、Server compare race If-None-Match === ETag If-Modified-Since >= LastModified ----> 5、得到一个结果将不输出另一个(ETag match ---》 res 304)
ETag code这段代码在Drash中可能不生效issuse--304 ETag Support
if(this.request.getHeaderParam('if-none-match') == "33a64df551425fcc55e4d42a148795d9f25f89d4"){ this.response.status_code = 304 } else { this.response.headers.set('ETag', "33a64df551425fcc55e4d42a148795d9f25f89d4") }
Vary 是一个HTTP响应头部信息,它决定了对于未来的一个请求头,应该用一个缓存的回复(response)还是向源服务器请求一个新的回复。
// 根据userAgent决定是否是用缓存,如pc和手机 Vary: User-Agent // zip or br 请求zip是用缓存 Vary: zip
作为面试高频面试题,一直通过博客去了解这个概念总是似懂非懂。我们知道的缓存有本地缓存浏览器缓存,浏览器缓存其实有两种方式,常用的http1缓存还有service worker策略缓存,本文主要介绍http缓存
缓存
什么是缓存?
什么是http cache
http cache
通过web cache
内置对象对Request
、Response
进行缓存,更多关于Cache
对象的内容,值得一提的是Cache
也可以作为Service Worker
生命周期的一部分。缓存的种类
MDN中将缓存大致分为两大类,私有缓存和共享缓存,你肯定联想到了
cache-control
的两个策略,这个我们稍后也会聊到这一点。其他缓存类型你也一定不会陌生,CDN缓存、网关缓存、反向代理缓存等。目标
缓存虽然不是必须的,但是重用缓存对于前端的交互提升还是巨大的。 缓存一般作用于
GET
请求,对其他请求一般无能为力,在service worker中这条可以忽略缓存控制
cache-control
cache-control
是http1.1
控制缓存机制的一个重要header
头,有以下几种形式: 1、no-store
不使用缓存机制,客户端每次都会重新请求服务器资源 2、no-cache
使用缓存,每次需要跟服务器确认是否需要,具体是否是用缓存根据客户端和服务端协议决定,也是通常所说的协商缓存,往往需要搭配其他header头使用ETag
、Last-Modified
等 3、public
指令表示该响应可以被任何中间人(比如cdn,网关)缓存 4、private
则表示该响应是专用于某单个用户的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中过期时间
过期时间有两种设置方式,两种方式代表的过期时间计算模式也完全不一致。
max-age
代表从上次更新到下次需要更新的最大缓存时间expires
是根据指定http-date
判断是否是用缓存下图是第一次请求后响应设置
expires
后,第二次请求内容显示from disk
即来自cache
不同get请求将不会缓存,这也是 revving (不频繁更新的文件会使用特定的命名方式:在URL后面(通常是文件名后面)会加上版本号。)来更新资源的实现。改方案也常用于现代打包工具。
Pragma
头 Pragma 是HTTP/1.0标准中定义的一个header属性,请求中包含Pragma的效果跟在头信息中定义Cache-Control: no-cache相同,但是HTTP的响应头没有明确定义这个属性,所以它不能拿来完全替代HTTP/1.1中定义的Cache-control头。通常定义Pragma以向后兼容基于HTTP/1.0的客户端。缓存验证
ETag
和LastModified
客户端将响应中的这两个的值转为请求中If-None-Match
和If-Modified-Since
两个值,并传给服务器,没有优先级之分ETag code这段代码在Drash中可能不生效issuse--304 ETag Support