浏览器HTTP缓存机制

   浏览器打开页面时,需要向服务器发送请求,请求静态文件(图片,css,js等),这些静态文件通常不会经常修改,客户端可以将这些不经常修改的静态文件存储起来。当客户端再次请求时,可以直接从本地缓存中读取,这样减少了http请求和服务器负担,加快客户端加载网页速度,提高用户体验,那么这个就是客户端缓存的意义了。

  Http 缓存机制作为 web 性能优化的重要手段,很多同学仅仅只是知道浏览器会对请求的静态文件进行缓存,但是为什么被缓存,缓存是怎样生效的,却并不是很清楚。我们首先了解http的传输原理,然后讲解http缓存机制。

1、HTTP的传输原理

这里写图片描述

HTTP想要发送一条报文的时候,需要经过以下两个步骤:

  • TCP三次握手建立起连接管道,HTTP报文会以流的形式通过该管道按顺序传输;
  • TCP会将这些数据分别切割成数据块,并且封装在IP分组中,通过IP去传输;

使用TCP作为传输层:

  • 传输可靠
  • 有序

一个HTTP请求过程如下图所示:

这里写图片描述

a. 浏览器在发起请求时首先会做什么?答,查找本地缓存

Expires:本地缓存目录中,文件过期的时间(由服务器指定具体的时间)

Cache-control:本地缓存目录中,文件过期的时间(由服务器指定过期的间隔时间,由于浏览器根据间隔生成具体的时间)

Last-Modified:服务器上文件的最后修改时间

Etag:文件标识

b. 浏览器查找完缓存之后接下来要做的是什么呢?答,DNS query

  首先客户机将域名查询请求发送到本地DNS服务器,本地DNS服务器先在之前的记录(缓存)中查找,如果有缓存,则直接利用缓存进行解析,如果没有缓存,则进入本地的缓存的寻找。如果本地服务器不能在本地找到缓存,则将请求发送到根域名DNS服务器。

  DNS服务器在拿到我们的域名后,会将它解析成IP地址返回给浏览器,这样浏览器就能直接定位到要请求的服务器的地址了。

c. 找到服务器地址之后肯定就是向服务器发送请求,建立连接,这个不用问了。

  这样根据IP和端口,浏览器就开始跟服务器建立TCP连接啦。看到TCP连接,我们就想到了三次握手。

  TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换 TCP窗口大小信息。

这里写图片描述

  • 第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;

  • 第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;

  • 第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。

完成了三次握手,客户端和服务器端就可以开始传送数据。

d. 浏览器在接收到服务器返回的数据后会怎么做呢?答,解析数据,生成渲染树

渲染展现页面是肯定的啦,关键是如何渲染。我们先来看一下浏览器的简单处理步骤:

(1)解析HTML/SVG/XHTML,build DOM树。

(2)解析CSS,build CSSOM树。

(3)build render树。render树并不等同于DOM树,因为一些像Header或display:none的东西就没必要放在render树中了。

(4)reflow。计算每个Element在设备中显示的具体位置。

(5)paint。最后通过调用操作系统Native GUI的API绘制。

2、http报文中与缓存相关的首部字段

  我们先来看看RFC2616规定的47种http报文首部字段中与缓存相关的字段,事先了解一下能让咱在心里有个底:

  • 通用首部字段(就是请求报文和响应报文都能用上的字段)
    这里写图片描述

  • 请求首部字段
    这里写图片描述

  • 响应首部字段
    这里写图片描述

  • 实体首部字段
    这里写图片描述

2、缓存规则解析

  HTTP缓存有多种规则,根据是否需要重新向服务器发起请求来分类,我将其分为两大类(强制缓存,对比缓存)

  在详细介绍这两种规则之前,先通过时序图的方式,让大家对这两种规则有个简单了解。

  已存在缓存数据时,仅基于强制缓存(Cache-control/Expires),请求数据的流程如下:

这里写图片描述

  已存在缓存数据时,仅基于对比缓存(Etag/Last-Modified),请求数据的流程如下:

这里写图片描述

  我们可以看到两类缓存规则的不同,强制缓存如果生效,不需要再和服务器发生交互,而对比缓存不管是否生效,都需要与服务端发生交互。

  两类缓存规则可以同时存在,强制缓存优先级高于对比缓存,也就是说,当执行强制缓存的规则时,如果缓存生效,直接使用缓存,不再执行对比缓存规则。

3、缓存优先级

这里写图片描述

Cache-control优先级高于Expires,Etag优先级高于Last-Modified

4、用户行为与缓存

这里写图片描述

a. 浏览器url回车、页面链接跳转、新开窗口、前进、后退

  浏览器发现缓存中有这个文件,就不发送任何请求了,直接去缓存中获取展现。(最快)

b. 按下F5刷新

  F5就是告诉浏览器,别偷懒,好歹去服务器看看这个文件是否有过期了。于是浏览器就胆胆襟襟的发送一个请求带上If-Modify-since。

  然后服务器发现:诶,这个文件我在这个时间后还没修改过,不需要给你任何信息了,返回304就行了。于是浏览器获取到304后就去缓存中欢欢喜喜获取资源了。

c. 按下Ctrl+F5

  这个可是要命了,告诉浏览器,你先把你缓存中的这个文件给我删了,然后再去服务器请求个完整的资源文件下来。于是客户端就完成了强行更新的操作。

5、参考链接

  网上已经有很多关于Cache-control、Expires、Etag、Last-Modified的经典讲解和实例演示,此处我就不再一一描述,大家参考以下链接:

浅谈浏览器http的缓存机制

彻底弄懂HTTP缓存机制及原理

浏览器的日常生活

你需要知道的HTTP常识

简析TCP的三次握手与四次分手

浏览器 HTTP 协议缓存机制详解

HTTP缓存机制详解

山水子农 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
坚持原创技术分享,您的支持将鼓励我继续创作!