We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
浏览器的缓存策略是由HTTP报文中与缓存相关的缓存标识(头部字段)来决定的。
常见的缓存标识有:
HTTP基于请求-应答模型,也就是浏览器发起请求,服务端响应请求。
在浏览器第一次发起请求时,会根据返回的响应报文中的缓存标识,来决定是否缓存响应结果。如果是则将响应结果与缓存标识一起存入浏览器缓存中。
由上图可以知道:
以上两点就是浏览器缓存机制的关键,它确保了每个请求的缓存存入与读取。
根据是否需要向服务器重新发起HTTP请求,可以将缓存过程分为两个部分,分别是:
强缓存决定了缓存能否直接使用,如果可以,则不需要发起请求,直接从缓存中读取资源,且会返回200的状态码。
控制强缓存的字段分别是Expires和Cache-Control,其中Cache-Control优先级比Expires高。
Expires
Cache-Control
表示该资源的绝对过期时间,如果没过期就可以直接使用,强缓存生效,不需要发起请求。
Expires: Wed, 22 Oct 2018 08:41:00 GMT
缺点是Expires受限于客户端时间,如果修改了客户端时间,可能会造成缓存失效。
为了弥补这种缺点,HTTP/1.1增加了Cache-Control
Cache-control: max-age=30
该属性值表示资源会在30秒后过期,需要再次请求。也就是说在30秒内如果再次发起该请求,则会直接使用缓存,强缓存生效。
它与Expires相比:
除了max-age之外,Cache-Control还有以下属性:
Cache-Control 的优先级高于 Expires,为了兼容 HTTP/1.0 和 HTTP/1.1,实际项目中两个字段都会设置。
如果强缓存失效了,例如:
如果出现了上述三种情况,强缓存失效,那就需要进行协商缓存。
浏览器需要携带协商缓存标识重新发起HTTP请求,来验证服务器资源是否有更新,会有两种结果:
控制协商缓存的的字段分别是:
Last-Modified表示该资源文件最后修改日期,If-Modified-Since 会将之前收到的 Last-Modified 的值发送给服务器,询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来并更新缓存,否则返回 304 状态码,表示可以继续使用缓存内容,并更新缓存有效期。
但这种根据更改时间的方式存在一些缺陷,例如:
为了解决Last-Modified 和 If-Modified-Since存在的问题,HTTP/1.1新增了这组缓存标识。
ETag类似资源指纹,是资源的唯一标识。当资源有变化时,Etag就会重新生成,If-None-Match 会将之前收到的 ETag 发送给服务器,询问该资源 ETag 是否变动,有变动的话就将新的资源发送回来并更新缓存,否则返回 304 状态码,表示可以继续使用缓存内容,并更新缓存有效期。
使用ETag就可以精确地识别资源的变动情况,就算是秒内的更新,也会让浏览器感知,能够更有效地利用缓存。
ETag同时支持强校验和弱校验。它们通过ETag标识符的开头是否存在“W/”来区分,如
"123456789" -- 一个强ETag验证符 W/"123456789" -- 一个弱ETag验证符
强 ETag 要求资源在字节级别必须完全相符,弱 ETag 在值前有个“W/”标记,只要求资源在语义上没有变化。
既然浏览器缓存了资源,那么资源会被缓存在哪呢?
根据上图浏览器控制台Network中的Size栏,可以看到有两个缓存位置:
内存缓存具有两个特点,分别是快速读取和时效性:
硬盘缓存是直接将缓存写入硬盘文件中,读取缓存需要对硬盘文件进行I/O操作,然后重新解析该缓存内容,读取速度比内存缓存慢。
既然有两个缓存位置,那么哪些资源会被放在内存缓存?哪些资源会被放在硬盘缓存?
因为CSS文件加载一次就可以渲染出来,我们不会频繁读取它,所以它不适合缓存到内存中。但是js之类的脚本却随时可能会执行,如果脚本在磁盘当中,我们在执行脚本的时候需要从磁盘取到内存中来,这样I/O开销就很大了,有可能导致浏览器失去响应。
访问缓存遵循以下原则:
大多项目都使用以下缓存方案:
彻底理解浏览器的缓存机制 实践这一次,彻底搞懂浏览器缓存机制
The text was updated successfully, but these errors were encountered:
No branches or pull requests
浏览器的缓存策略是由HTTP报文中与缓存相关的缓存标识(头部字段)来决定的。
常见的缓存标识有:
缓存过程分析
HTTP基于请求-应答模型,也就是浏览器发起请求,服务端响应请求。
在浏览器第一次发起请求时,会根据返回的响应报文中的缓存标识,来决定是否缓存响应结果。如果是则将响应结果与缓存标识一起存入浏览器缓存中。
由上图可以知道:
以上两点就是浏览器缓存机制的关键,它确保了每个请求的缓存存入与读取。
根据是否需要向服务器重新发起HTTP请求,可以将缓存过程分为两个部分,分别是:
强缓存
强缓存决定了缓存能否直接使用,如果可以,则不需要发起请求,直接从缓存中读取资源,且会返回200的状态码。
控制强缓存的字段分别是
Expires
和Cache-Control
,其中Cache-Control
优先级比Expires
高。Expires(HTTP/1.0)
表示该资源的绝对过期时间,如果没过期就可以直接使用,强缓存生效,不需要发起请求。
缺点是Expires受限于客户端时间,如果修改了客户端时间,可能会造成缓存失效。
为了弥补这种缺点,HTTP/1.1增加了
Cache-Control
Cache-Control(HTTP/1.1)
该属性值表示资源会在30秒后过期,需要再次请求。也就是说在30秒内如果再次发起该请求,则会直接使用缓存,强缓存生效。
它与Expires相比:
除了max-age之外,Cache-Control还有以下属性:
总结
Cache-Control 的优先级高于 Expires,为了兼容 HTTP/1.0 和 HTTP/1.1,实际项目中两个字段都会设置。
协商缓存
如果强缓存失效了,例如:
如果出现了上述三种情况,强缓存失效,那就需要进行协商缓存。
浏览器需要携带协商缓存标识重新发起HTTP请求,来验证服务器资源是否有更新,会有两种结果:
控制协商缓存的的字段分别是:
其中Etag/If-None-Match的优先级比Last-Modified/If-Modified-Since高
Last-Modified 和 If-Modified-Since(HTTP/1.0)
Last-Modified表示该资源文件最后修改日期,If-Modified-Since 会将之前收到的 Last-Modified 的值发送给服务器,询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来并更新缓存,否则返回 304 状态码,表示可以继续使用缓存内容,并更新缓存有效期。
但这种根据更改时间的方式存在一些缺陷,例如:
Etag 和 If-None-Match(HTTP/1.1)
为了解决Last-Modified 和 If-Modified-Since存在的问题,HTTP/1.1新增了这组缓存标识。
ETag类似资源指纹,是资源的唯一标识。当资源有变化时,Etag就会重新生成,If-None-Match 会将之前收到的 ETag 发送给服务器,询问该资源 ETag 是否变动,有变动的话就将新的资源发送回来并更新缓存,否则返回 304 状态码,表示可以继续使用缓存内容,并更新缓存有效期。
使用ETag就可以精确地识别资源的变动情况,就算是秒内的更新,也会让浏览器感知,能够更有效地利用缓存。
ETag的强弱
ETag同时支持强校验和弱校验。它们通过ETag标识符的开头是否存在“W/”来区分,如
强 ETag 要求资源在字节级别必须完全相符,弱 ETag 在值前有个“W/”标记,只要求资源在语义上没有变化。
缓存位置
既然浏览器缓存了资源,那么资源会被缓存在哪呢?
根据上图浏览器控制台Network中的Size栏,可以看到有两个缓存位置:
memory cache(内存缓存)
内存缓存具有两个特点,分别是快速读取和时效性:
disk cache(硬盘缓存)
硬盘缓存是直接将缓存写入硬盘文件中,读取缓存需要对硬盘文件进行I/O操作,然后重新解析该缓存内容,读取速度比内存缓存慢。
资源的缓存位置
既然有两个缓存位置,那么哪些资源会被放在内存缓存?哪些资源会被放在硬盘缓存?
因为CSS文件加载一次就可以渲染出来,我们不会频繁读取它,所以它不适合缓存到内存中。但是js之类的脚本却随时可能会执行,如果脚本在磁盘当中,我们在执行脚本的时候需要从磁盘取到内存中来,这样I/O开销就很大了,有可能导致浏览器失去响应。
访问缓存优先级
访问缓存遵循以下原则:
缓存方案
大多项目都使用以下缓存方案:
参考
彻底理解浏览器的缓存机制
实践这一次,彻底搞懂浏览器缓存机制
The text was updated successfully, but these errors were encountered: