浏览器缓存

32 阅读6分钟

一、简介

推荐文章:developer.mozilla.org/en-US/docs/…

浏览器缓存主要指http缓存,其机制是根据http报文的缓存标识进行相应操作

使用浏览器可以减少向服务器发送请求,节省带宽、减轻服务器的请求负担、加快客户端的访问速度。

二、缓存方式

推荐文章:zhuanlan.zhihu.com/p/111190645

浏览器缓存分两种:强缓存和协商缓存

1、强缓存

1)、用户第一次访问页面之后,服务器在返回资源的同时,会在Response Headers中写入expires首部或cache-control,标识缓存的过期时间,并且将对应资源进行缓存。

2)、当再次请求该资源的时候,缓存会对date(Date 是一个通用首部,表示原始服务器消息发出的时间。即表示的是首次请求某个资源的时间)和expires/cache-control的时间进行对比,是否需要重新加载资源。

3)、控制强制缓存的字段分别是Expires和Cache-Control,其中Cache-Control优先级比Expires高。

上面的200 from memory cache和200 from disk cache属于强制缓存。

2、协商缓存

1)、首次请求资源时,服务器在返回资源的同时,会在Response Headers中写入Last-Modified首部,表示该资源在服务器上的最后修改时间

2)、当再次请求该资源时,会在Request Headers 中写入If-Modified-Since首部,此时的If-Modified-Since的值是首次请求资源时所返回的Last-Modified的值。

3)、服务器接收到请求后,会根据If-Modified-Since的值判断资源在该日期之后是否发生过变化,服务器接收到请求后,会根据If-Modified-Since的值判断资源在该日期之后是否发生过变化

4)、与协商缓存有关的字段是Last-Modified/IF-Modified-Since、Etag/IF-None-Match。

Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

三、缓存加载过程

推荐文章:

1、developer.mozilla.org/en-US/docs/…

2、www.cnblogs.com/duiniweixia…

从上图可以明显看到,加载资源相同时,加载速度 memory cache > disk cache > 协商缓存 > 不缓存

内存缓存(from memory cache) :内存缓存具有两个特点,分别是快速读取和时效性:

1)、快速读取:内存缓存会将编译解析后的文件,直接存入该进程的内存中,占据该进程一定的内存资源,以方便下次运行使用时的快速读取。

2)、时效性:一旦该进程关闭,则该进程的内存则会清空。

硬盘缓存(from disk cache): 硬盘缓存则是直接将缓存写入硬盘文件中,读取缓存需要对该缓存存放的硬盘文件进行I/O操作,然后重新解析该缓存内容,读取复杂,速度比内存缓存慢。

浏览器会在js和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache);

而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)。

statussize说明
200memory cache状态码是灰色的,从内存中读取之前已经加载过的资源,不请求服务器,页面关闭时,资源就会被内存释放,再次打开相同页面不会出现此类情况,在同一页面刷新才会出现。一般脚本、字体、图片会存在内存当中
200disk cache状态码是灰色的,从磁盘中读取之前已经加载过的资源,不请求服务器,页面关闭不会被释放,这部分资源存在电脑磁盘里,只有用户手动清除浏览器缓存的时候才会释放。一般非脚本会存在磁盘当中,如css等
200数值大小从服务器下载最新资源,数值是从服务器获取的全部资源大小
304数值大小访问服务器,发现资源没有更新,使用本地资源。数值是与服务器通信报文的大小,并不是资源本身的大小。

四、用户行为会对缓存产生影响

用户操作Expire/Cache-ControlLast-Modified/Etag
地址栏回车、页面链接跳转、新开窗口、前进后退、有效有效
F5刷新无效有效
Ctrl+F5强制刷新无效无效

五、配置方式

1、不缓存(协商缓存)

vue和react项目在index.html模板的中添加配置

<meta http-equiv="pragma" content="no-cache"  />
<meta http-equiv="content-type" content="no-cache, must-revalidate" />
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate" />
<meta http-equiv="expires" content="0"/>

HTTP1.0中通过Pragma 控制页面缓存,可以设置:Pragma或no-cache

HTTP1.1中启用Cache-Control 来控制页面的缓存与否,常用的参数:
no-cache,浏览器和缓存服务器都不应该缓存页面信息;
public,浏览器和缓存服务器都可以缓存页面信息;
no-store,请求和响应的信息都不应该被存储在对方的磁盘系统中;
must-revalidate,对于客户机的每次请求,代理服务器必须想服务器验证缓存是否过时;
Last-Modified只页面的最后生成时间,GMT格式;
Expires过时期限值,GMT格式,指浏览器或缓存服务器在该时间点后必须从真正的服务器中获取新的页面信息;

2、协商缓存和强缓存并用

nginx在location添加配置

location / {
  root /app/web/res/; #静态资源路径
  if ($request_filename ~* .*.(?:htm|html)$) {
      #add_header Cache-Control no-store;  # 不缓存,no-store不管什么情况都传输整个文件大小
      #add_header Cache-Control no-cache;  # 协商缓存,no-cache只有在文件改变时才会传输整个文件大小
      add_header Cache-Control "no-store, no-cache";
  }
  #if ($request_filename ~* .*.(?:js|css)$) {
  #        expires 300d;
  #}
  if ($request_uri ~* .*[.].(?:js|css|map|jpg|png|svg|ico)$) {
      add_header Cache-Control "public, max-age=2592000"; #非html缓存一个月
  }
  index index.html
}
#location ~* ^/api {
#  proxy_pass http://192.168.6.6:8080;
#  client_max_body_size 5120M;
#  proxy_read_timeout 600; 
#  proxy_request_buffering off;
#  proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
#}

六、总结

强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存。