前端缓存

前端缓存

前端缓存主要是分为HTTP缓存和浏览器缓存。其中HTTP缓存是在HTTP请求传输时用到的缓存,主要在服务器代码上设置;而浏览器缓存则主要由前端开发在前端js上进行设置。

缓存可以说是性能优化中简单高效的一种优化方式了。一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷。

对于一个数据请求来说,可以分为发起网络请求、后端处理、浏览器响应三个步骤。浏览器缓存可以帮助我们在第一和第三步骤中优化性能。比如说直接使用缓存而不发起请求,或者发起了请求但后端存储的数据和前端一致,那么就没有必要再将数据回传回来,这样就减少了响应数据。

缓存过程

浏览器与服务器通信的方式为应答模式,即是:浏览器发起HTTP请求 – 服务器响应该请求。那么浏览器第一次向服务器发起该请求后拿到请求结果,会根据响应报文中HTTP头的缓存标识,决定是否缓存结果,是则将请求结果和缓存标识存入浏览器缓存中。

  • 浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识
  • 浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中

缓存作用

  • 减少了冗余的数据传输,节省了网费。
  • 减少了服务器的负担, 大大提高了网站的性能
  • 加快了客户端加载网页的速度

缓存分类

  • 强制缓存如果生效,不需要再和服务器发生交互,而对比缓存不管是否生效,都需要与服务端发生交互
  • 两类缓存规则可以同时存在,强制缓存优先级高于对比缓存,也就是说,当执行强制缓存的规则时,如果缓存生效,直接使用缓存,不再执行对比缓存规则

强制缓存

在缓存数据未失效的情况下,可以直接使用缓存数据,那么浏览器是如何判断缓存数据是否失效呢? 在没有缓存数据的时候,浏览器向服务器请求数据时,服务器会将数据和缓存规则一并返回,缓存规则信息包含在响应header中。

image.png

对比缓存

  • 对比缓存需要进行比较判断是否可以使用缓存。
  • 浏览器第一次请求数据时,服务器会将缓存标识与数据一起返回给客户端,客户端将二者备份至缓存数据库中。
  • 再次请求数据时,客户端将备份的缓存表示发送给服务器,服务器根据缓存标识进行判断,判断成功后返回304状态码。通知客户端比较成功,可以使用缓存数据。

image.png

请求流程

第一次请求

浏览器开始请求 -> 无缓存 -> 向web服务器请求 -> 请求响应,缓存协商 -> 呈现

是否缓存Expries,Cache-Control 缓存时间 Etag Last-Modifyed

第二次请求

image.png

通过最后修改时间来判断缓存是否可用

  1. Last-Modified: 响应时告诉客户端对比此资源的最后修改时间.
  2. If-Modified-Since: 当资源过期时使用Cache-Control表示的max-age,发现资源具有Last-Modified声明,则再次向服务器请求时带上IF-Modified-Since。
  3. 服务器收到请求后发现带有If-Modified-Since标识则与被请求资源的最后修改时间进行对比,若最后修改时间较新,说明资源又被改动过,则响应最新的资源并返回200状态码
  4. 若最后修改时间和If-Modified-Since一样,说明资源没有被修改,则响应304标识未更新,告诉浏览器继续使用所保存的缓存文件。

最后修改时间存在的问题

  • 某些服务器不能精确到的文件的最后修改时间,这样就无法通过最后修改时间来判断文件是否更新了。
  • 某些文件的修改非常频繁,在秒以下的时间内进行修改,Last-Modified只能精确到秒。
  • 一些文件的最后修改时间改变了,但是内容并未改变,我们不希望客户端认为这个文件修改。
  • 如果同样的一个文件位于多个CDN服务器上的内容虽然一样,修改时间不一样。

Etag

Etag是实体标签的缩写,根据是实体内容生成的一段hash字符串,可以表示资源的状态。当资源发生改变时,Etag也随之发生变化。Etag是web服务端产生的,然后发给浏览器客户端。

  • 当客户端先判断缓存是否可以使用之前获取的缓存中文档中的ETag时,然后通过If-None-Match发送请求给Web服务器询问次缓存是否可用。
  • 服务器收到请求,将服务器中的此文件的Etag,跟请求头中的If-None-Match相比较,如果值是一样的,说明缓存还是最新的,web服务器将发送304 Not Modified响应码给客户端表示缓存未修改,可用使用缓存。
  • 如果不一样则web服务器将发送该文件的最新版本给浏览器客户端。

如何干脆不发送请求

  • 浏览器会将文件缓存到Cache目录中,第二次请求时浏览器会先检查Cache目录下是否有该文件,如果有,并且还没有到Expires设置的时间,即文件未过期,那么此时浏览器将直接从Cache目录中读取文件,而不再发送请求.
  • Expires是服务器响应的消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存中读取数据,而无需再次请求,这是HTTP1.0的内容,现在浏览器均默认使用HTTP1.1
  • Cache-Control与Expires的作用一致,都是指当前资源的有效期,控制浏览器是否直接从浏览器缓存读取数据还是重新发送请求到服务器读取数据,如果未设置的话,其优先级高于Expires。

Cache-Control

  • private 客户端可以缓存
  • public:客户端和代理服务器都可以缓存
  • max-age=60 缓存内容将在60秒后失效
  • no-cache 需要使用对比缓存验证数据,强制向服务器再次验证
  • no-store 所有内容都不会缓存,强制缓存和对比缓存都不会触发

浏览器缓存

本地存储小容量

  • Cookie:主要用于用户信息的存储,Cookie的内容可以自动在请求的时候被传递给服务器。
  • LocalStorage: 数据将一直保存在浏览器内,直到用户清除浏览器缓存数据为止。
  • SessionStorage: SessionStorage的其他属性同LocalStorage,只不过它的生命周期同标签页的生命周期,当标签页被关闭时,SessionStorage也会被清除。
容量 作用
Cookie 4KB 请求时传递
localStorage 5MB 永久存储
SessionStorage 5MB 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。

本地储存大容量

WebSql和IndexDB主要用在前端有大容量存储需求的页面上,例如,在线编辑浏览器或者网页邮箱。

说明 状态
WebSql 关系型数据库 废弃
IndexDB 非关系数据库 正常使用

往返缓存

往返缓存又称为BFCache,是浏览器在前进后退按钮上为了提升历史页面的渲染速度的一种策略。该策略具体表现为,当用户前往新页面时,将当前页面的浏览器DOM状态保存到bfcache中;当用户点击后退按钮的时候,将页面直接从bfcache中加载,节省了网络请求的时间。

参考链接

前端缓存详解

深入理解浏览器的缓存机制