浏览器缓存详解
louzhedong opened this issue · 0 comments
浏览器缓存
缓存贯穿于浏览器访问的方方面面,深入理解缓存能带给我们的程序更高效的性能
但缓存使用不当也会对我们的开发造成困惑
缓存的类型
-
强缓存
用户发送的请求,直接从客户端缓存中获取,不与服务器发生交互
-
协商缓存
用户发送的请求,需要到达服务器,由服务器判断是否从缓存中获取资源
-
注意点:
客户端最后获取到的数据最后都是从客户端缓存中获取的,在协商缓存中由服务端判断是否使用客户端中的缓存
强缓存
强缓存包括 expires 和 cache-control
expires是http1.0的内容,在高级的浏览器中会被cache-control覆盖掉
expires中保存的是服务器的过期时间,当客户端和服务器时间不一致时,缓存会出现偏差
cache-control的类型:
-
public:所有内容都将被缓存(客户端和代理服务器都可缓存)
-
private:所有内容只有客户端可以缓存,Cache-Control的默认取值
-
no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
-
no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
-
max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效
-
s-maxage:只用于共享缓存,比如CND缓存。如果存在s-maxage,则会覆盖max-age和expires
cache-control的判断流程可以查看下图:
协商缓存
协商缓存分类
- If-Modified-Since 和 Last-Modified
- If-None-Match 和 Etag
其中后者会覆盖前者,它们各自的含义:
-
Last-modified: 表明请求的资源上次的修改时间。
-
If-Modified-Since:客户端保留的资源上次的修改时间。
-
Etag:资源的内容标识。(不唯一,通常为文件的md5或者一段hash值,只要保证写入和验证时的方法一致即可)
-
If-None-Match: 客户端保留的资源内容标识。
1) 分布式系统尽量关闭Etag,因为每台机器生成的Etag都不一样。
2)分布式系统里多台机器间文件的Last-Modified必须一致,以免负载均衡不同导致对比失败。
Last-Modified的问题:
- 文件的内容并没有发生改变(我删除了一个字母,然后又加上,重新保存),这样也会导致文件修改时间改变。
- 文件修改时间的单位是精度是秒,而当修改过于频繁,在秒一下单位修改,那么就会导致文件已经修改但是修改时间没有变
- 每个CDN保存文件的修改时间可能不一样
缓存的来源
-
from disk cache
从磁盘中获取缓存资源,等待下次访问时不需要重新下载资源,而直接从磁盘中获取。它的直接操作对象为CurlCacheManager。
-
from memory cache
从内存中获取资源,等待下次访问时不需要重新下载资源,而直接从内存中获取。Webkit早已支持memoryCache。
目前Webkit资源分成两类,一类是主资源,比如HTML页面,或者下载项,一类是派生资源,比如HTML页面中内嵌的图片或者脚本链接,分别对应代码中两个类: MainResourceLoader和SubresourceLoader。虽然Webkit支持memoryCache,但是也只是针对派生资源,它对应的类为CachedResource,用于保存原始数据(比如CSS,JS等),以及解码过的图片数据。 -
比较
当退出进程时,内存中的数据会被清空,而磁盘的数据不会,所以,当下次再进入该进程时,该进程仍可以从diskCache中获得数据,而memoryCache则不行。