浏览器缓存详解

本文详述了浏览器缓存的各个方面,包括缓存的意义、浏览器缓存的分类、HTTP缓存概述、过期机制、验证机制以及易混淆内容。通过对缓存生命周期的解析,阐述了服务器如何设置资源有效期、浏览器如何判断资源是否过期以及如何进行验证。此外,还讨论了缓存的存储位置、选择机制以及常见的误解。最后,提到了内存缓存与硬盘缓存的区别,并附上了相关参考文档。
摘要由CSDN通过智能技术生成
引言

其实关于浏览器缓存的内容网上已经不胜枚举,之所以产出本文的目的是,遇到缓存相关的问题后,在网上看到的所有相关内容大都雷同对细节的描述都不够全面。因此阅读了缓存相关的RFC文档及浏览器内核的实现文档等对缓存相关内容进行整理。

在了解浏览器缓存之前,我们不妨先谈谈缓存的意义。这里引用RFC文档上的一句话:缓存如果不能用以提升性能,那么它就毫无用处。以HTTP缓存为例,如果缓存未过期那么就减少了网络请求,如果缓存通过验证那么就减少了传输资源大小。而关于过期与验证机制的讲解将在下文中展开。

顺便一提,本文详细的给出了参考链接以便阅读者对其中任何一个部分感兴趣时可以找到更加详细的参考资料。


浏览器缓存概述

浏览器缓存可以从多个维度进行抽象分类。在广义上来讲无论是memory cache、service worker、push cache、http cache都属于浏览器缓存的概念,而大部分时候我们提到浏览器缓存的概念往往是指http cache。其实对于浏览器而言还有一种回退缓存(page cache),

以下我们来关注几种浏览器可能会发生缓存的场景:

  • 资源预加载: 如preloader ,preload、prefetch。preloader与preload不同是资源预加载期,例如在标记化时,可能需要的css资源就已经被预先加载到memory cache中了。而资源预加载技术,通过link实现。可以将项目中可能用到的数据先请求过来以备页面使用。数据存放于内存缓存( memory cache)。参考:https://calendar.perfplanet.com/2013/big-bad-preloader/
  • 服务端推送: 这里是指http2的服务端推送,而非客户端轮询。是一种服务器根据某种规则推送客户端将可能用到的资源来减少请求时间的技术。数据存放于push cache。推送缓存中的数据仅可以使用一次,之后将可能根据协议头存在于http缓存中。参考:https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/
  • service worker: Service workers 本质上充当 客户端与服务端之间的代理服务器。这个 API 创建了有效的离线体验,它会拦截网络请求并根据网络是否可用采取来适当的动作、更新来自服务器的的资源。它还提供入口以推送通知和访问后台同步 API。server woker的缓存不同于http 缓存,由server worker自身接管,存储在server worker 参考:https://w3c.github.io/ServiceWorker/#cache-objects
  • 重复的网络资源请求: 常见的网络资源请求,可以根据协议头将资源存储在硬存中,以备下一次使用(http cache),相对于内存缓存,可以进行持久化的存储,而不会局限于单次会话。参考:https://www.rfc-editor.org/rfc/inline-errata/rfc7234.html
  • 页面回退:想象有这样一种场景,你点进了一个博客,顺着博客的链接你进了另一篇文章,当你回退的时候是否会觉得上一个页面似乎很快就会退了而非重新进行了一遍加载。这就是浏览器为了浏览器性能实现的页面回退机制(Page Cache)。不过此种机制往往不存在于页面内资源寻找的过程,是一种浏览器自身不受开发者控制的实现机制。
    参考:https://calendar.perfplanet.com/2013/big-bad-preloader/

以上缓存的读取顺序为: (Memory Cache/Preload Cache) -> Service Worker -> (Disk Cache/HTTP cache) -> Push Cache

而本文主要以Http Cache的描述为主,关于Service worker以及Server Push如果感兴趣可以通过参考链接进行过了解。


HTTP缓存概述

缓存的目标是通过重用先前的响应消息以满足当前请求,来显着提高性能。

让我们来看一个小例子以便于理解:
这天浏览器请求一个叫做海绵宝宝.jpg的资源,服务器给了浏览器一张图片。当浏览器再一次请求服务器海绵宝宝.jpg时,
服务器说:大哥,未来30天图都不会变,你就不能存起来下次别来管我要了吗?我太累了。并在响应里写到,这个图30天都不变。
于是浏览器在这30天里遇到这张图的请求都会使用缓存的图片以响应。
第31天时,浏览器又遇到了海绵宝宝.jpg的请求。于是他问服务器:海绵宝宝.jpg变了吗
服务器答道:没变
又过了一段时间,遇到这个请求时浏览器又去问服务器
服务器说:变了。并给了浏览器一张图片。
浏览器这次就用新的图片响应了请求。

记住本文的主角:浏览器和海绵宝宝.jpg,我们将在后文多处看到他们。(是的,服务器在本文只是配角)
前情提要:在后面我们会讲述:

  • 服务器如何告知图片资源海绵宝宝.jpg的有效期
  • 浏览器如何计算图片是否过期(要知道这图片是服务器转交给浏览器的)
  • 服务器如何根据信息得知浏览器的资源是不是有效的(毕竟服务器不止和一个浏览器对话,无法记忆只能计算)
  • 如果某次,服务器没有告知海绵宝宝.jpg这张图片资源的过期信息,浏览器还会存储资源吗
  • 浏览器的缓存中可能有很多张海绵宝宝.jpg资源吗,如果有会怎么选择呢
  • 浏览器会如何缓存海绵宝宝.jpg(要知道浏览器要处理很多请求,除了海绵宝宝.jpg,可能还有派大星.jpg,他们需要被区分)

简单的来说当我们请求一个请求一个本地存在响应缓存的资源时,浏览器并不会立即发起网络请求。而是对缓存的新鲜度(freshness)进行一个判定,如果该响应是可以使用的,那么就会直接使用缓存资源以减少延迟和网络开销)。

如果缓存资源已经陈旧了,那么就会对缓存资源进行验证。如果验证通过,那么浏览器仍然可以复用资源,以减少网络传输的资源大小。如果没有通过,则源服务器应当在验证请求中返回资源,而不是仅仅告诉浏览器该缓存不可使用。

强缓存与协商缓存:现在的许多资料中都将未过期可直接使用的缓存称为强制缓存。过期了需要验证的缓存称为协商缓存。但是实际上RFC文档中并未给出这样的定义。也就是说这两个概念属于理解性的概念而非规范性的概念

为了简单理解可以先参考下面这张图。但是这里隐去很多细节,随着后文对内容的不断扩充,我们会完善这张图。
在这里插入图片描述

以上简述,描述了网络资源请求使用缓存的一个大致过程。以下将详细描述过期验证机制。


过期机制

还记得上面海绵宝宝图片的例子吗,我们现在需要来解决第一个问题,即服务器如何告知图片资源海绵宝宝.jpg的有效期。为了解决这个问题,则需要一种规范来明确定义如何说明进行资源缓存机制。这种规范必须是双方都可以理解的。在HTTP1.1中,可以使用Cache-Control的缓存指令,以实现缓存机制。

在使用浏览器决定对一个内容进行缓存之前,他将会判定内容是否为可以缓存的。

  • 如果缓存指令被设置为no-store,则不
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值