深入理解HTTP/浏览器缓存机制

概述

浏览器请求资源时,并不是直接发起http请求,而是会先检查本地有没有该文件的缓存,如果本地有未过期缓存,那么就不用发起http请求了,直接使用本地缓存(强缓存),这样可以大大加快网页响应速度;如果本地有缓存但是过期了,那么浏览器需要向服务器发起一个http请求询问该文件有没有修改过,如果有修改过,服务器返回新的文件,如果没有修改过,服务器返回304状态码及空响应体,浏览器收到该响应后会继续使用本地缓存(协商缓存)

缓存的目的就是减少不必要的资源加载时间,加快网页响应速度,提升用户体验。

那么,在整个过程中,浏览器如何判断缓存是否过期?缓存的位置在哪里?服务器如何判断文件是否修改过?带着这些问题我们继续往下看

缓存的两个阶段:强缓存协商缓存

强缓存

强缓存的过程 :当浏览器首次请求资源时,服务器会将缓存规则放在http响应头字段里和响应体一同返回给浏览器,控制强缓存的响应头字段是ExpiresCache-Control ,浏览器收到后,会将响应结果和缓存标识存入浏览器缓存中,当下次再次请求该资源时,会先在缓存里查找,如果找到了并且未过期,则直接使用该缓存,不再发送http请求,此时network里的状态码是一个灰色的200。

Expires:HTTP1.0 的特性,标识该资源过期的时间点。它的值是标准时间格式,如 Wed, 22 Nov 2019 08:41:00 GMT。即在这个时间点之后,缓存的资源过期。

缺点:服务端和客户端时间不一致的话,就会有误差。

Cache-Control

是HTTP1.1 提出的特性,主要为了弥补Expires的缺陷,取值为:

max-age:xxx(number):有效时间xxx秒,是一个相对值

public:客户端和代理服务器都可以缓存

private:只有客户端可以缓存

no-cache:走协商缓存,与服务器确认文件是否修改

no-store:不缓存,请求最新资源

s-maxage:针对代理服务器的缓存时间

注意:为了兼容各版本http协议,通常两个头部同时设置,当同时存在时,Cache-Control比Expires优先级高。

缓存的位置

打开浏览器network tab的size列,可以看到缓存的位置:

from memory cache(内存缓存)

存在于当前进程中,容量小,读取速度快。

存活时间短,当浏览器标签页关闭时,进程结束,内存缓存也就不存在了

from disk cache(硬盘缓存)

存在于磁盘中,容量大,需要I/O读写操作,所以速度比内存缓存慢

不随进程的结束而销毁,存储时间长

注意⚠️:刚开始从硬盘中读取,读取之后将比较小的文件保存在内存中,所以当刷新页面,部分文件的缓存位置会变为from memory cache

协商缓存

协商缓存过程:

当强缓存时间过期了,才会进入协商缓存阶段,上面说到,首次请求时服务器会将缓存相关的头字段放入响应报文里,其中也包含协商缓存相关的头字段,如Last-Modified 和Etag, 当强缓存失效时,浏览器会携带协商缓存字段If-Modified-Since和 If-None-Match 向服务器发起请求,If-Modified-Since 的值就是服务器之前返回的Last-Modified 的值,If-None-Match 的值就是Etag的值, 服务器根据此头字段判断文件在上次请求后有没有修改过,如果没有修改过,返回状态码304,并且响应体为空加快传输速度,如果修改过,返回200状态码和新文件内容。

Last-Modified / If-Modified-Since

HTTP1.0 的特性,Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间。当强缓存失效,浏览器会携带If-Modified-Since向服务器发起请求,服务器收到该请求,则会根据If-Modified-Since的字段值与该资源在服务器的最后被修改时间做对比,若服务器的资源最后被修改时间大于If-Modified-Since的字段值,则重新返回资源,状态码为200;否则则返回304,代表资源无更新,可继续使用缓存文件。

缺陷:

  1. Last-Modified精度只有秒级,当在一秒内再次请求该资源,即使文件修改过,也会返回304,导致客户端使用了旧的缓存。
  2. 编辑了文件,但内容并没有更改,(比如加一个字然后又把它删了)这样也会造成缓存失效。

Etag / If-None-Match

HTTP1.1 的特性,Etag是服务器响应请求时,返回当前资源文件的一个唯一标识,它是根据实体内容生成的一段 hash 字符串,由服务端产生。每当文件有修改,hash都会重新生成,就会与之前的不一样,服务器由此判断文件被修改过。

当强缓存失效,浏览器会携带If-None-Match向服务器发起请求,服务器收到该请求,则会根据If-None-Match的字段值与该资源在服务器的Etag值做对比,一致则返回304,代表资源无更新,继续使用缓存文件;不一致则重新返回资源文件,状态码为200

注意⚠️:为了兼容各版本http协议,通常两种头部字段同时设置,当同时存在时,Etag / If-None-Match比Last-Modified / If-Modified-Since优先级高。

Etag 对比 Last-Modified

1.在精准度上,ETag优于Last-Modified

  • Last-Modified精度只有妙级

  • 如果编辑了文件,但内容并没有更改,(比如加一个字然后又把它删了)Last-Modified也会改变

2.在性能上,Last-Modified优于ETag

  • Last-Modified仅仅只是记录一个时间点,而 Etag需要根据文件的具体内容生成哈希值,需要使用哈希算法去计算,有一定的时间复杂度。

总结

用一个思维导图总结:

相关推荐
茂茂在长安4 分钟前
Linux 命令大全完整版(11)
java·linux·运维·服务器·前端·centos
知识分享小能手37 分钟前
Html5学习教程,从入门到精通,HTML5 简介语法知识点及案例代码(1)
开发语言·前端·javascript·学习·前端框架·html·html5
IT、木易39 分钟前
大白话React第二章深入理解阶段
前端·javascript·react.js
Good Note41 分钟前
Golang的静态强类型、编译型、并发型
java·数据库·redis·后端·mysql·面试·golang
晚安7201 小时前
Ajax相关
前端·javascript·ajax
图书馆钉子户1 小时前
怎么使用ajax实现局部刷新
前端·ajax·okhttp
bin91531 小时前
DeepSeek 助力 Vue 开发:打造丝滑的单选按钮(Radio Button)
前端·javascript·vue.js·ecmascript·deepseek
qianmoQ1 小时前
第五章:工程化实践 - 第五节 - Tailwind CSS 常见问题解决方案
前端·css
那就可爱多一点点1 小时前
超高清大图渲染性能优化实战:从页面卡死到流畅加载
前端·javascript·性能优化
lisanndesu1 小时前
HTTPS
网络协议·http·https