咱们常常经过缓存技术来加快网站的访问速度,从而提高用户体验。HTTP协议中也规定了一些和缓存相关的Header,来容许浏览器或共享高速缓存缓存资源。这些Header包括:浏览器
以上Header又能够分红两种类型:缓存
本文将会分别介绍这四种配置的做用以及可能产生的影响。服务器
Last-Modified:服务器在响应请求时,告知浏览器资源的最后修改时间。函数
If-Modified-Since:浏览器再次发送请求时,会经过此Header通知服务器在上次请求时所获得的资源最后修改时间。服务器会将If-Modified-Since与被请求资源的最后修改时间进行比对。若资源的最后修改时间晚于If-Modified-Since,表示资源已被改动,则响最新的资源,返回200状态码;若资源的最后修改时间早于或等于If-Modified-Since,表示浏览器端的资源已是最新版本,响应304状态码,通知浏览器继续使用缓存中的资源。性能
ETag:服务器分配给资源的惟一标识符,资源被修改后,ETag也会随之发生变化。测试
If-None-Match:浏览器再次发送请求时,会经过此Header通知服务器已缓存资源的ETag。服务器会将If-None-Match与被请求资源的最新ETag进行比对。若不相同,表示资源已被改动,则响应最新的资源,返回200状态码;若值相同,则直接响应304状态码,通知浏览器继续使用缓存中的资源。网站
服务器能够经过此Header向浏览器传递一个具体的时间(格林威治格式,例如:Thu, 19 Jul 2018 07:43:05 GMT) ,来明确地宣告资源的有效期。在资源过时以前,浏览器再也不发送请求,而是直接从缓存中读取数据。只有当资源过时以后,浏览器才会再次向服务器请求该资源。阿里云
服务器使用此Header来向客户端建议缓存策略,它有一下几个可选值:spa
max-age=秒:告知浏览器缓存的有效时长,在该时间内浏览器将直接从缓存中读取数据。3d
s-maxage=秒:做用同max-age,可是只对共享高速缓存(如CDN)有效,对浏览器无效。
no-cache:告知浏览器不要直接使用缓存,而是必须向服务器发送请求。
no-store:告知浏览器不要缓存本次请求和响应的任何信息。
public:宣告任何缓存媒介均可以缓存该响应。
private:宣告该响应只容许个体客户端(如浏览器)去缓存,而不容许共享高速缓存(如CDN)去缓存。
在上面的介绍中咱们了解到浏览器会根据max-age设置的时间进行缓存。而经过研究发现CDN也会识别源站响应头中Cache-Control属性,根据max-age设置的时间进行缓存,可是,若是源站同时设置了s-maxage和max-age,那么CDN会优先采用s-maxage。
下面经过图例来展现一下这些可选值的效果。
首先了解一下浏览器是怎样根据max-age进行缓存的:
从上图不难发现,服务器在Header中返回了Cache-Control: max-age=100后,浏览器成功缓存100秒,该时间段内的请求都从直接以本地缓存来响应。
那么,服务器在Header中返回Cache-Control:s-maxage=100时,又会对浏览器产生什么样的影响呢?
如上图所示,浏览器没有采起任何缓存策略,这是由于s-maxage面向的是共享高速缓。
上面这两个例子很容易理解,在现实世界中,为了加快网站响应速度,咱们可能会在浏览器和服务器之间引入CDN服务。浏览器的请求会先到达CDN,而后CDN判断是从缓存中读取数据仍是回源到服务器。接下来,让咱们看看max-age和s-maxage会对CDN的缓存策略带来哪些影响。
能够看出CDN也会利用max-age来缓存,因此在100秒内强制刷新浏览器时,CDN会直接用缓存来响应。
若是服务器使用了s-maxage又会如何呢?
不难发现CDN对max-age和s-maxage采起了一样的缓存策略,但浏览器并不会根据s-maxage来进行缓存。
CDN供应商的特殊规则
咱们分别测试了阿里云和腾讯云的CDN对Cache-Control的支持状况,发现他们都有一些独特的规则。
阿里云CDN能够在控制台里设置Cache-Control,该设置会覆盖源服务器的Cache-Control。
腾讯云CDN虽然没有再控制台提供覆盖Cache-Control的功能,但其规则却一点也不简单,在使用的时候必定要特别注意:
若是同时设置了这些Header,浏览器和高速共享缓存会按照下面的优先级进行缓存:
Cache-Control > Expires > ETag > Last-Modified
也就是说,Cache-Control不只是强缓存,并且拥有最高的优先级,咱们能够为不常常发生变化的资源应用该Header来提高响应时间。
Ada提供了UI脚手架和API脚手架,这两类脚手架的服务器端入口文件分别为index.server.js和index.js,咱们只须要在入口文件的请求处理函数中为响应添加适当的Header,便可通知客户端进行响应的缓存,好比:
// 设置CDN缓存300秒,浏览器缓存200秒
ctx.response.headers.set('Cache-Control', public,s-maxage=300,max-age=200
)
在为请求添加缓存Header以前,应该先为其制定适当的缓存策略,须要考虑该URL是否适合缓存(数据是否特定于用户)以及须要缓存的时长等等。
总结
经过使用这些HTTP Header,咱们能够主动影响浏览器甚至CDN的缓存策略,从而减小请求数量,提高网页性能,减轻服务器压力。
Ada的灵活机制能让咱们为不一样的URL设置不一样的缓存策略,可以更有针对性地进行主动缓存。