当前位置: 首页 > news >正文

浏览器缓存机制

简单来说,浏览器缓存就是把一个已经请求过的资源拷贝一份存储起来,当下次需要该资源时,浏览器会根据缓存机制决定直接使用缓存资源还是再次向服务器发送请求。

如下图所示是我在第二次打开某个网页时的资源请求图,可以看出里面大部分资源是从浏览器直接读取了缓存。

那么浏览器缓存究竟有什么作用呢?

浏览器缓存最主要的作用是减少网络传输的损耗以及降低服务器压力

接下来我将通过以下几个部分来探讨浏览器缓存机制:

  • 缓存位置
  • 缓存策略

缓存位置

浏览器缓存位置分为四种,其优先级顺序如下:

  1. Service Worker
  2. Memory Cache
  3. Disk Cache
  4. Push Cache

当上述四个缓存位置中的缓存都没有命中时,则会向服务器发起请求。

Service Worker

Service Worker 是一个注册在指定源和路径下的事件驱动 worker。它采用 JavaScript 控制关联的页面或者网站,拦截并修改访问和资源请求,细粒度地缓存资源。

我们可以通过谷歌开发者工具中的 Application -> Service Workers 查看当前缓存的资源。

Memory Cache

Memory Cache 即内存中的缓存,其特点是容量小、读取高效、持续性短,会随着进程的释放而释放。

所以,在内存使用率低、缓存小尺寸资源时,会以 Memory Cache 为优先,否则使用 Disk Cache。

Disk Cache

Disk Cache 即磁盘中的缓存,其特点是容量大、读取缓慢、持续性长,任何资源都能存储到磁盘中。

所以,在内存使用率高、缓存大尺寸资源时,会以 Disk Cache 为优先。

Push Cache

Push Cache 是 HTTP 2.0 中的内容,其缓存时间也很短暂,只在会话(Session)中存在,一旦会话结束就被释放。

缓存策略

浏览器每次在向服务器发起 HTTP 请求获得资源后,可能会根据不同情况(可能是代码控制如 Service Worker、Push Cache,也可能是根据 HTTP Header 的缓存标识字段)将资源缓存起来。

浏览器缓存策略分为强制缓存协商缓存,其是通过设置 HTTP Header 来实现的。

强制缓存

当浏览器发起 HTTP 请求时,会依次查找上述缓存位置中是否存在缓存资源并通过缓存标识字段 Expires 或 Cache-Control 来验证缓存资源是否过期。

Expires 是服务器端在响应请求时用来规定资源的失效时间。

Cache-Control 是服务器端在响应请求时用来规定资源是否需要被浏览器缓存以及缓存的有效时间等。

Cache-Control 主要取值如下:

Expires 是 HTTP 1.0 的字段,而 Cache-Control 是 HTTP 1.1 的字段,当 Expires 与 Cache-Control 同时存在时,Cache-Control 的优先级要高于 Expires

若是命中缓存(即存在缓存资源并且缓存资源未过期),则浏览器响应 HTTP Status Code 200,并直接使用缓存资源作为返回结果,不需要发起 HTTP 请求;若是存在缓存资源但缓存资源已过期,则进入协商缓存

协商缓存

与协商缓存相关的缓存标识字段是 Last-ModifiedEtag

Last-Modified 是服务器端在响应请求时用来说明资源的最后修改时间。与之对应的是 If-Modified-Since 字段,在协商缓存过程中,浏览器发送的 HTTP 请求中 Header 中会带上 If-Modified-Since 字段,值为缓存资源 Last-Modified 属性的值。

当服务器端接收到带有 If-Modified-Since 的请求时,则会将 If-Modified-Since 的值与被请求资源的最后修改时间做对比。如果相同,说明资源没有新的修改,则响应 HTTP Status Code 304,浏览器会继续使用缓存资源;如果最后修改时间比较新,则说明资源被修改过,则响应 HTTP Status Code 200,并返回最新的资源。

Etag 是服务器端在响应请求时用来说明资源在服务器端的唯一标识。与之对应的是 If-None-Match 字段,在协商缓存过程中,浏览器发送的 HTTP 请求中 Header 中会带上 If-Modified-Since 字段,值为该缓存资源 Etag 属性的值。

当服务器端接收到带有 If-None-Match 的请求时,则会将 If-None-Match 的值与被请求资源的唯一标识做对比。如果相同,说明资源没有新的修改,则响应 HTTP Status Code 304,浏览器会继续使用缓存资源;如果不同,则说明资源被修改过,则响应 HTTP Status Code 200,并返回最新的资源。

Last-Modified 是 HTTP 1.0 的字段,而 Etag 是 HTTP 1.1 的字段,当 Last-Modified 与 Etag 同时存在时,Etag 的优先级要高于 Last-Modified

Etag 的出现主要是为了解决 Last-Modified 存在的问题:

  • Last-Modified 标注的最后修改只能精确到秒级,如果某些文件在 1 秒钟以内被修改多次的话,它将不能准确标注文件的最后修改时间;
  • 如果本地打开缓存文件,即使没有对文件进行修改,但 Last-Modified 却改变了,导致文件没法使用缓存;

下面用一张流程图来完整说明当浏览器发起 HTTP 请求时缓存机制的过程:


公众号不定时分享个人在前端方面的学习经验,欢迎关注。

相关文章:

  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • vue--为什么data属性必须是一个函数
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • 【翻译】babel对TC39装饰器草案的实现
  • Fabric架构演变之路
  • CSS实用技巧干货
  • Objective-C 中关联引用的概念
  • 鱼骨图 - 如何绘制?
  • Centos安装gerrit
  • 模型微调
  • 专属程序员的西游记,不是程序员读不懂哦?
  • 第十八天-企业应用架构模式-基本模式
  • 人脸识别最新开发经验demo
  • 百度地图api文档实现任意两点之间的最短路线规划
  • 链表
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • canvas 高仿 Apple Watch 表盘
  • CSS相对定位
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • mysql 数据库四种事务隔离级别
  • SpiderData 2019年2月25日 DApp数据排行榜
  • Vue 动态创建 component
  • Yii源码解读-服务定位器(Service Locator)
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 将 Measurements 和 Units 应用到物理学
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 入手阿里云新服务器的部署NODE
  • 深度学习在携程攻略社区的应用
  • 使用 Docker 部署 Spring Boot项目
  • 项目实战-Api的解决方案
  • 学习ES6 变量的解构赋值
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • #if和#ifdef区别
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (5)STL算法之复制
  • (初研) Sentence-embedding fine-tune notebook
  • (二)斐波那契Fabonacci函数
  • (翻译)terry crowley: 写给程序员
  • (九)One-Wire总线-DS18B20
  • (一)Thymeleaf用法——Thymeleaf简介
  • (一)认识微服务
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转)Windows2003安全设置/维护
  • .net 8 发布了,试下微软最近强推的MAUI
  • .NET企业级应用架构设计系列之结尾篇
  • .Net下C#针对Excel开发控件汇总(ClosedXML,EPPlus,NPOI)
  • .skip() 和 .only() 的使用
  • /boot 内存空间不够
  • @Autowired @Resource @Qualifier的区别
  • @RunWith注解作用
  • [【JSON2WEB】 13 基于REST2SQL 和 Amis 的 SQL 查询分析器