资讯专栏INFORMATION COLUMN

http缓存深入研究,200 from cache or 304 not modified?

binaryTree / 2068人阅读

摘要:我把缓存分为缓存存储缓存对比两部分。不过是的东西,现在默认浏览器均默认使用,所以它的作用基本忽略。当资源发送改变时,也随之发生变化。关于版本号建议使用的形式而不是。

前几天看到一篇关于缓存的文章彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法,觉得很有意思,所以打算系统学习下Http缓存相关的知识。

我把缓存分为缓存存储缓存对比两部分。

基本概念

命中缓存速度对比

200 from cache  vs  304 Not Modified 

思考:localStorage存储

(一)基本概念 (1)缓存存储

Pragma : no-cache  http1.0时期的属性  为了兼容会使用

Expires:0  http1.0时期的属性 

Cache-Control  http1.1 中加入的新属性,它有以下常用参数:

Public/Private 私有缓存/共有缓存

no-cache:不建议使用本地缓存,但仍然会缓存到本地

no-store:不会在客户端缓存任何数据

max-age:比较特殊,是一个混合属性,替代了Expires的过期时间

举个栗子:如果要设置客户端不缓存,并兼容http1.0的方式可以这样写:

Pragma : no-cache 
Expires:0
Cache-Control:no-store

等价于

Pragma : no-cache  // Pragma为了兼容http1.0
Cache-Control:max-age=0  // 去掉了Expires属性(下面名词解释会说到为什么被去掉),合并到max-age中,

名词解释:
私有缓存:《HTTP权威指南》里面讲到了私有缓存的一种就是在浏览器里面输入  about:cache  可以查看自己浏览器缓存的内容,会给出一个显示了缓存内容“磁盘缓存统计”页面,这个可以看看还挺有意思,能展示不少信息
Expires:过时期限值,GMT格式,是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。不过Expires 是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。Expires 的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大(比如时钟不同步,或者跨时区),那么误差就很大,所以在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代。

(2)缓存对比

Last-Modified  http1.0时期属性  现在仍在使用

ETag(Entity Tag)  http1.1时期新加属性 ,使用inode+mtime(以下有解释)来计算。根据实体内容生成的一段hash字符串(类似于MD5或者SHA1之后的结果),可以标识资源的状态。 当资源发送改变时,ETag也随之发生变化。

名词解释:
inode :包含文件的元信息,包括以下内容

文件的字节数、文件拥有者的User ID、文件的Group ID

文件的读、写、执行权限

文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文>件内容上一次变动的时间,atime指文件上一次打开的时间。

链接数,即有多少文件名指向这个inode、 文件数据block的位置
mtime:指文件内容上一次变动的时间

2.1为什么用http1.1新推出了ETag

某些服务器不能精确得到文件的最后修改时间, 这样就无法通过最后修改时间来判断文件是否更新了。

某些文件的修改非常频繁,在秒以下的时间内进行修改. Last-Modified只能精确到秒。

一些文件的最后修改时间改变了,但是内容并未改变。 我们不希望客户端认为这个文件修改了。

2.2ETag有哪些问题

ETag也有他自己的问题,所以经常在使用中会关闭ETag。举例来说,同一个文件在不同物理机上的inode是不同的,这就导致了在分布式的Web系统中,当访问落在不同的物理机上时会返回不同的ETag,进而导致304失效,降级为200请求。解决办法也有从ETag算法中剥离inode,只是使用mtime,但是这样实际上和Last-Modified就一样了。当然你也可以额外的做一些改进,使ETag对静态资源的算法也是通过hash计算的。不过由于一般我们会使用CDN技术,因此集群部署中的ETag问题并不会造成太大的影响,所以折腾的人也不太是很多。  参考:这篇文章hefangshi同学的回答

(二)命中缓存速度对比

图片描述
引一张《HTTP权威指南》中的一张图,可以看出命中缓存过程:

(1)缓存命中速度

缓存命中 > 缓存再验证成功 > 缓存未命中 = 缓存再验证失败;

1.1缓存命中优先级

Cache-Control http1.1 > Expires > Pragma http1.0来决定是否 (200 from cache)

1.2缓存再验证成功

根据Last-Modified http1.0 和 ETaghttp1.1 来验证是否返回 (304 Not Modified) 两者都有,就必须同时验证,并且两者都满足才会返回304;

图片描述

服务端响应头 Last-Modified 与 客户端请求头 If-Modified-Since 对应

服务端响应头 ETag 与 客户端请求头 If-None-Match

(三) 200 from cache vs 304 Not Modified

为什么有时候明明命中了缓存,控制台中Status显示的不是 200 from cache ?原来是浏览器的原因:

触发 200 from cache:

直接点击链接访问

输入网址按回车访问

二维码扫描

触发 304 Not Modified:

刷新页面时触发

设置了长缓存、但 Entity Tags 没有移除时触发

二者怎么选择

毫无疑问选择可以尽量多的命中缓存,然后靠更新静态文件的版本号来使缓存失效。关于版本号建议使用 file.xxx.js 的形式而不是 file.js?v=xxx。

可以看这两篇文章有讲述原因:

Best Practices for Speeding Up Your Web Site

大公司里怎样开发和部署前端代码

(四)思考

在研究缓存问题的时候,知乎上看到这个问题:静态资源(JS/CSS)存储在localStorage有什么缺点?为什么没有被广泛应用? ,看了大神们的答案主要是维护成本实在过高,如果真的速度超快,这点可以忽略,值得花时间研究,但是如果读取再执行的速度可能会比浏览器直接304性能要低,就完全没有必要使用这种方式了。

(五 )参考文章:

配置错误产生的差距:200 OK (FROM CACHE) 与 304 NOT MODIFIED 

http://www.benhallbenhall.com/2012/03/http-codes-200-from-cache-304/

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/61846.html

相关文章

  • 性能优化-http缓存

    摘要:整个请求响应链的缓存机制必须遵循的特别指令。基本的缓存机制就是由这些参数形成的。如果此文章中有什么问题的话,烦请一定要指出,谢谢参考资料缓存机制浅析移动端加载性能优化浅谈浏览器的缓存机制 之前对http的缓存知识一知半解,只能说出个大概。和同事交流这块内容时稍一深入探讨就捉襟见肘,自惭形秽。故痛定思痛,花了一两天时间去研究了下这块内容,写下这篇笔记方便以后的查询与修正。 首先介绍下和缓...

    Aceyclee 评论0 收藏0
  • 漫谈Web缓存

    摘要:了解前端缓存是打造高性能网站的必要知识。这个表示,你的请求发送到后端,后端判断并认为资源可以继续使用,直接使用本地缓存。尽可能的设置久缓存时间,通过码来管理版本。参考链接浅谈缓存权威指南上配置缓存首发地址 背景说明 缓存一直是前端性能优化中,浓墨重彩的一笔。了解前端缓存是打造高性能网站的必要知识。 之前,对于缓存的认知一直停留在看《HTTP权威指南》和一些相关帖子的深度,过了一段时...

    davidac 评论0 收藏0
  • 漫谈Web缓存

    摘要:了解前端缓存是打造高性能网站的必要知识。这个表示,你的请求发送到后端,后端判断并认为资源可以继续使用,直接使用本地缓存。尽可能的设置久缓存时间,通过码来管理版本。参考链接浅谈缓存权威指南上配置缓存首发地址 背景说明 缓存一直是前端性能优化中,浓墨重彩的一笔。了解前端缓存是打造高性能网站的必要知识。 之前,对于缓存的认知一直停留在看《HTTP权威指南》和一些相关帖子的深度,过了一段时...

    Carl 评论0 收藏0
  • 漫谈Web缓存

    摘要:了解前端缓存是打造高性能网站的必要知识。这个表示,你的请求发送到后端,后端判断并认为资源可以继续使用,直接使用本地缓存。尽可能的设置久缓存时间,通过码来管理版本。参考链接浅谈缓存权威指南上配置缓存首发地址 背景说明 缓存一直是前端性能优化中,浓墨重彩的一笔。了解前端缓存是打造高性能网站的必要知识。 之前,对于缓存的认知一直停留在看《HTTP权威指南》和一些相关帖子的深度,过了一段时...

    shuibo 评论0 收藏0
  • 从前端角度理解缓存

    摘要:缓存的概念分很多种,本次讨论的主要就是前端缓存中的缓存。从字面理解,强制缓存的方式简单粗暴,给设置了过期时间,超过这个时间之后过期需要重新请求。这个方法简单直接,直接设定一个绝对的时间当前时间缓存时间。然后从缓存中读取数据。 缓存的概念分很多种,本次讨论的主要就是前端缓存中的Http缓存。 缓存是怎么回事 前端发送请求主要经历以下三个过程,请求->处理->响应。如果有多次请求就需要重复...

    Astrian 评论0 收藏0

发表评论

0条评论

binaryTree

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<