浏览器缓存之http缓存

426 阅读6分钟

最近做项目遇到了浏览器缓存导致页面数据没有更新。以及页面样式未更新的情况。这是因为浏览器缓存导致的。所以来总结一下浏览器缓存的知识。

良好的缓存策略可以降低资源的重复加载提高网页的整体加载速度。针对现在的vue、react的单页面应用,在做性能优化这块,缓存策略也是必须考虑的。

缓存带来的好处

  1. 减少冗余的数据传输,节省带宽。
  2. 减轻服务器的请求负担,有缓存就可以少向服务器发送请求,尤其是对于一些访问量大的网站这点还是很重要的。
  3. 资源从缓存中读取,无需向服务器发送请求再等待返回,加快了客户端的访问速度。

缓存带来的问题

如果项目更新了,但是用户访问时浏览器读取的是缓存资源,那么用户就获取不到最新的页面,影响用户使用。

缓存分类

web缓存分为很多种,比如数据库缓存、代理服务器缓存、CDN缓存,以及浏览器缓存。 浏览器通过代理服务器向源服务器发起请求的原理如图。

2.png

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

http缓存存机制

主要是根据http报文的缓存标识进行响应操作。

http状态码

在讨论浏览器缓存之前,我们先看看网页相关的http状态码,打开控制台,在Network下捕捉请求,注意Status和Size栏,会看到200 from disk cache,200数值大小。 3.png

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

浏览器三级缓存原理

  1. 内存缓存:读取速度最快
  2. 本地缓存:读取速度快
  3. 网络缓存:读取速度最慢

缓存流程

  1. 先查找内存,如果内存中存在,从内存中加载;
  2. 如果内存中未查找到,选择硬盘获取,如果硬盘中有,从硬盘中加载;
  3. 如果硬盘中未查找到,那就进行网络请求,加载到的资源缓存到硬盘和内存;

缓存策略

通常浏览器的缓存策略分为两种:

  • 强缓存
  • 协商缓存

强缓存:Expires&Cache-Control

强制缓存就是,用户第一次访问页面之后,浏览器将数据存在缓存中,在过期时间之内,都不会再请求服务器。是否使用强制缓存在于资源是否过期,该过期时间从第一次请求的服务器响应头中获取。如果在过期时间内,从缓存中读取,如果超出过期时间,则使用协商缓存。

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

Cache-Control头

HTTP/1.1定义的 Cache-Control 头用来区分对缓存机制的支持情况, 请求头和响应头都支持这个属性。通过它提供的不同的值来定义缓存策略。

在请求头中使用时,可选值有:

字段说明
no-store没有缓存:缓存中不得存储任何关于客户端请求和服务端响应的内容。每次由客户端发起的请求都会下载完整的响应内容。
no-cache缓存但重新验证:如下头部定义,此方式下,每次有请求发出时,缓存会将此请求发到服务器(译者注:该请求应该会带有与本地缓存相关的验证字段),服务器端会验证请求中所描述的缓存是否过期,若未过期(注:实际就是返回304),则缓存才使用本地缓存副本。
private私有:响应是专用于某单个用户的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中。
public响应可以被任何中间人(译者注:比如中间代理、CDN等)缓存
max-age过期机制中,最重要的指令是 "max-age=",表示资源能够被缓存(保持新鲜)的最大时间。
must-revalidate验证方式:意味着缓存在考虑使用一个陈旧的资源时,必须先验证它的状态,已过期的缓存将不被使用。

协商缓存:Last-Modified&Etag

协商缓存,从字面意思,就是要协商,是浏览器和服务器协商,那么浏览器每次都要和服务器通信。在第一次请求服务器时,服务器会返回资源,并且返回一个资源的缓存标识,一起存到浏览器的缓存数据库。当第二次请求资源时,浏览器会首先将缓存标识发送给服务器,服务器拿到标识后判断标识是否匹配,如果不匹配,表示资源有更新,服务器会将新数据和新的缓存标识一起返回到浏览器;如果缓存标识匹配,表示资源没有更新,并且返回 304 状态码,浏览器就读取本地缓存服务器中的数据。

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

Etag

作为缓存的一种强校验器,如果资源请求的响应头里含有ETag, 客户端可以在后续的请求的头中带上 If-None-Match 头来验证缓存。

Last-Modified

Last-Modified作为一种弱校验器,说它弱是因为它只能精确到一秒。如果响应头里含有这个信息,客户端可以在后续的请求中带上 If-Modified-Since 来验证缓存。

vary响应

Vary HTTP 响应头决定了对于后续的请求头,如何判断是请求一个新的资源还是使用缓存的文件。

当缓存服务器收到一个请求,只有当前的请求和原始(缓存)的请求头跟缓存的响应头里的Vary都匹配,才能使用缓存的响应。

参考链接:

blog.csdn.net/feiyu_may/a…

developer.mozilla.org/zh-CN/docs/…