浅谈浏览器缓存

最近在项目中遇到了IE浏览器因缓存问题未能成功向后端发送GET类型请求的bug,而后顺藤摸瓜顺便看了看缓存的知识,以为有必要总结一下。php

在前端开发中,性能一直都是被你们所重视的一点,然而判断一个网站的性能最直观的就是看网页打开的速度。其中提升网页反应速度的一个方式就是使用缓存。一个优秀的缓存策略能够缩短网页请求资源的距离,减小延迟,而且因为缓存文件能够重复利用,还能够减小带宽,下降网络负荷。css

1. 介绍

web缓存是指一个web资源(如html页面,图片,js,数据等)存在于web服务器和客户端(浏览器)之间的副本。html

缓存会根据进来的请求保存输出内容的副本;当下一个请求来到的时候,若是是相同的URL,缓存会根据缓存机制决定是直接使用副本响应访问请求,仍是向源服务器再次发送请求。比较常见的就是浏览器会缓存访问过网站的网页,当再次访问这个URL地址的时候,若是网页没有更新,就不会再次下载网页,而是直接使用本地缓存的网页。只有当网站明确标识资源已经更新,浏览器才会再次下载网页。至于浏览器和网站服务器是如何标识网站页面是否更新的机制,将在后面介绍。前端

1.1 web缓存的做用

web缓存的做用显而易见:web

  1. 减小网络带宽消耗
    不管对于网站运营者或者用户,带宽都表明着金钱,过多的带宽消耗,只会便宜了网络运营商。当Web缓存副本被使用时,只会产生极小的网络流量,能够有效的下降运营成本。
  2. 下降服务器压力
    给网络资源设定有效期以后,用户能够重复使用本地的缓存,减小对源服务器的请求,间接下降服务器的压力。同时,搜索引擎的爬虫机器人也能根据过时机制下降爬取的频率,也能有效下降服务器的压力。
  3. 减小网络延迟,加快页面打开速度
    带宽对于我的网站运营者来讲是十分重要,而对于大型的互联网公司来讲,可能有时由于钱多而真的不在意。那Web缓存还有做用吗?答案是确定的,对于最终用户,缓存的使用可以明显加快页面打开速度,达到更好的体验。

1.2 web缓存的类型

web缓存大体能够分为如下几种类型数据库

  1. 数据库数据缓存
  2. 服务器端缓存
  3. 浏览器端缓存
  4. web应用层缓存

浏览器经过代理服务器向源服务器发起请求的原理以下图:后端

clipboard.png

浏览器先向代理服务器发起web请求,再将请求转发到源服务器。它属于共享缓存,因此不少地方均可以使用其缓存资源,所以对于节省流量有很大做用。浏览器

浏览器缓存是将文件保存在客户端,在同一个会话过程当中会检查缓存的副本是否足够新,在后退网页时,访问过的资源能够从浏览器缓存中拿出使用。经过减小服务器处理请求的数量,用户将得到更快的体验缓存

下面着重关注一下浏览器缓存。安全

2. web缓存的工做原理

全部的缓存都是基于一套规则来帮助他们决定何时使用缓存中的副本提供服务(假设有副本可用的状况下,未被销毁回收或者未被删除修改)。这些规则有的在协议中有定义(如HTTP协议1.0和1.1),有的则是由缓存的管理员设置(如DBA、浏览器的用户、代理服务器管理员或者应用开发者)。

2.1 浏览器端的缓存规则

对于浏览器端的缓存来说,这些规则是在HTTP协议头和HTML页面的Meta标签中定义的。他们分别从新鲜度校验值两个维度来规定浏览器是直接使用缓存中的副本,仍是须要去源服务器获取更新的版本。

  1. 新鲜度(过时机制):也就是缓存副本有效期。一个缓存副本必须知足如下任一条件,浏览器会认为它是有效的,足够新的,而直接从缓存中获取副本并渲染:

    • 含有完整的过时时间控制头信息(HTTP协议报头),而且仍在有效期内
    • 浏览器已经使用过这个缓存副本,而且在一个会话中已经检查过新鲜度
  2. 校验值(验证机制):服务器返回资源的时候有时在控制头信息带上这个资源的实体标签Etag(Entity Tag),它能够用来做为浏览器再次请求过程的校验标识。如过发现校验标识不匹配,说明资源已经被修改或过时,浏览器需求从新获取资源内容。

2.2 浏览器缓存的控制

2.2.1 使用HTML的 Meta 标签

<META HTTP-EQUIV="Pragma" CONTENT="no-cache">

上述代码的做用是告诉浏览器当前页面不被缓存,每次访问都须要去服务器拉取。使用上很简单,但只有部分浏览器能够支持,并且全部缓存代理服务器都不支持,由于代理不解析HTML内容自己。
能够经过这个页面测试你的浏览器是否支持:Pragma No-Cache Test

2.2.2 使用缓存有关的HTTP消息报头

一个URI的完整HTTP协议交互过程是由HTTP请求和HTTP响应组成的。有关HTTP详细内容可参考《Hypertext Transfer Protocol — HTTP/1.1》《HTTP协议详解》等。

在HTTP请求和响应的消息报头中,常见的与缓存有关的消息报头有:

clipboard.png

  1. Cache-Control
    cache-control的种类这么多,然而怎么使用它们呢:
    clipboard.png

    1. max-age(单位为s)指定设置缓存最大的有效时间,定义的是时间长短。当浏览器向服务器发送请求后,在max-age这段时间里浏览器就不会再向服务器发送请求了。
      咱们来找个资源看下。好比QQ推广上的css资源,max-age=3600,也就是说缓存有效期为3600秒(也就是1h)。因而在1小时内都会使用这个版本的资源,即便服务器上的资源发生了变化,浏览器也不会获得通知。max-age会覆盖掉Expires,后面会有讨论。

      clipboard.png

    2. s-maxage(单位为s)同max-age,只用于共享缓存(好比CDN缓存)。
      好比,当s-maxage=60时,在这60秒中,即便更新了CDN的内容,浏览器也不会进行请求。也就是说max-age用于普通缓存,而s-maxage用于代理缓存。若是存在s-maxage,则会覆盖掉max-age和Expires header。
    3. public 指定响应会被缓存,而且在多用户间共享。也就是下图的意思。若是没有指定public仍是private,则默认为public。

      clipboard.png

    4. private 响应只做为私有的缓存(见下图),不能在用户间共享。若是要求HTTP认证,响应会自动设置为private。

      clipboard.png

    5. no-cache 指定不缓存响应,代表资源不进行缓存,可是设置了no-cache以后并不表明浏览器不缓存,而是在获取缓存前要向服务器确认资源是否被更改。所以有的时候只设置no-cache防止缓存仍是不够保险,还能够加上private指令,将过时时间设为过去的时间。
    6. no-store 绝对禁止缓存,一看就知道若是用了这个命令固然就是不会进行缓存啦~每次请求资源都要从服务器从新获取。
    7. must-revalidate 指定若是页面是过时的,则去服务器进行获取。这个指令并不经常使用,就不作过多的讨论了。
  2. Expires
    缓存过时时间,用来指定资源到期的时间,是服务器端的具体的时间点。也就是说, Expires=max-age + 请求时间 ,须要和Last-modified结合使用。但在上面咱们提到过,cache-control的优先级更高。 Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过时时间前浏览器能够直接从浏览器缓存取数据,而无需再次请求。

    clipboard.png

  3. Last-modified & If-modified-since
    服务器端文件的最后修改时间,须要和cache-control共同使用,是检查服务器端资源是否更新的一种方式。当浏览器再次进行请求时,会向服务器传送If-Modified-Since报头,询问Last-Modified时间点以后资源是否被修改过。若是没有修改,则返回码为304,使用缓存;若是修改过,则再次去服务器请求资源,返回码和首次请求相同为200,资源为服务器最新资源。
  4. Etag & & If-None-Match
    根据实体内容生成一段hash字符串,标识资源的状态,由服务端产生。浏览器会将这串字符串传回服务器,验证资源是否已经修改,若是没有修改,过程以下:

    clipboard.png

2.2.3 缓存报头种类与优先级

  1. Cache-Control与Expires
    Cache-ControlExpires的做用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据仍是从新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,若是同时设置的话,其优先级高于Expires
  2. Last-Modified与ETag
    Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的惟一标识符,可以更加准确的控制缓存。Last-Modified与ETag是能够一块儿使用的,服务器会优先验证ETag,一致的状况下,才会继续比对Last-Modified,最后才决定是否返回304。
    你可能会以为使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为何还须要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:

    • Last-Modified标注的最后修改只能精确到级,若是某些文件在1秒钟之内,被修改屡次的话,它将不能准确标注文件的新鲜度
    • 若是某些文件会被按期生成,当有时内容并无任何变化,但Last-Modified却改变了,致使文件无法使用缓存
    • 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
  3. Last-Modified/ETag 与 Cache-Control/Expires
    配置Last-Modified/ETag的状况下,浏览器再次访问统一URI的资源,仍是会发送请求到服务器询问文件是否已经修改,若是没有,服务器会只发送一个304回给浏览器,告诉浏览器直接从本身本地的缓存取数据;若是修改过那就整个数据从新发给浏览器;
    Cache-Control/Expires则不一样,若是检测到本地的缓存仍是有效的时间范围内,浏览器直接使用本地副本,不会发送任何请求。二者一块儿使用时,Cache-Control/Expires的优先级要高,即当本地副本根据Cache-Control/Expires发现还在有效期内时,则不会再次发送请求去服务器询问修改时间Last-Modified或实体标识Etag了。
    通常状况下,二者会配合一块儿使用,由于即便服务器设置缓存时间, 当用户点击“刷新”按钮时,浏览器会忽略缓存继续向服务器发送请求,这时Last-Modified/ETag将可以很好利用304,从而减小响应开销。

2.2.4 哪些请求不能被缓存?

没法被浏览器缓存的请求:

  • HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告诉浏览器不用缓存的请求
  • 须要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的
  • 通过HTTPS安全加密的请求(有人也通过测试发现,ie其实在头部加入Cache-Control:max-age信息,firefox在头部加入Cache-Control:Public以后,可以对HTTPS的资源进行缓存,参考《HTTPS的七个误解》)
  • POST请求没法被缓存
  • HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求没法被缓存

3. 使用缓存流程

一个用户发起一个静态资源请求的时候,浏览器会经过如下几步来获取并展现资源:

clipboard.png

缓存行为主要由缓存策略决定,而缓存策略由内容拥有者设置。这些策略主要经过特定的HTTP头部来清晰地表达。

以上过程也能够被归纳为三个阶段:

  1. 本地缓存阶段:先在本地查找该资源,若是有发现该资源,并且该资源尚未过时,就使用这一个资源,彻底不会发送http请求到服务器;
  2. 协商缓存阶段:若是在本地缓存找到对应的资源,可是不知道该资源是否过时或者已通过期,则发一个http请求到服务器,而后服务器判断这个请求,若是请求的资源在服务器上没有改动过,则返回304,让浏览器使用本地找到的那个资源;
  3. 缓存失败阶段:当服务器发现请求的资源已经修改过,或者这是一个新的请求(在原本没有找到资源),服务器则返回该资源的数据,而且返回200, 固然这个是指找到资源的状况下,若是服务器上没有这个资源,则返回404。

4. 用户操做行为与缓存的关系

用户在使用浏览器的时候,会有各类操做,好比输入地址后回车,按F5刷新等,这些行为会对缓存有什么影响呢?

clipboard.png

经过上表咱们能够看到,当用户在按F5进行刷新的时候,会忽略Expires/Cache-Control的设置,会再次发送请求去服务器请求,而Last-Modified/Etag仍是有效的,服务器会根据状况判断返回304仍是200;
而当用户使用Ctrl+F5进行强制刷新的时候,只是全部的缓存机制都将失效,从新从服务器拉去资源。

  • 普通刷新 – 当按下F5或者点击刷新按钮来刷新页面的时候,浏览器将绕过本地缓存来发送请求到服务器, 此时, 协商缓存是有效的
  • 强制刷新 – 当按下ctrl+F5来刷新页面的时候, 浏览器将绕过各类缓存(本地缓存和协商缓存), 直接让服务器返回最新的资源
  • 回车或转向 – 当在地址栏上输入回车或者按下跳转按钮的时候, 全部缓存都生效

5. 如何从缓存角度改善站点

详细信息

  • 同一个资源保证URL的稳定性
  • 给css、js、图片等资源增长HTTP缓存头,并强制入口html不被缓存
  • 减小对Cookie的依赖
  • 减小对HTTPS加密协议的使用
  • 多用Get方式请求动态Cgi
  • 动态CGI也是能够被缓存

网上的帖子大多深浅不一,甚至有些先后矛盾,在下的文章都是学习过程当中的总结,若是发现错误,欢迎留言指出~

参考:
Web缓存机制系列
浅谈web缓存
Web先后端缓存技术
浏览器缓存机制:不一样浏览器对用户操做行为处理比较

PS:欢迎你们关注个人公众号【前端下午茶】,一块儿加油吧~

另外能够加入「前端下午茶交流群」微信群,长按识别下面二维码便可加我好友,备注加群,我拉你入群~

相关文章
相关标签/搜索