带你搞懂浏览器缓存

1、缓存顺序

当依次查找缓存且都没有命中的时候,才会去请求网络。浏览器缓存机制的优先级排列如下:

  • Service Worker
  • Memory Cache
  • Disk Cache
  • Push Cache
1.1Service Worker
  • Service Worker 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全。Service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。

  • Service Worker 实现缓存功能一般分为三个步骤:首先需要先注册 Service Worker,然后监听到 install 事件以后就可以缓存需要的文件,那么在下次用户访问的时候就可以通过拦截请求的方式查询是否存在缓存,存在缓存的话就可以直接读取缓存文件,否则就去请求数据。

  • 如果我们没有在 Service Worker 命中缓存的话,会根据缓存查找优先级去查找数据。但是不管我们是从 Memory Cache 中还是从网络请求中获取的数据,浏览器都会显示我们是从 Service Worker 中获取的内容。

1.2.Memory Cache
  • Memory Cache 也就是内存中的缓存,主要包含的是当前中页面中已经抓取到的资源,如样式、脚本、图片等。关闭 Tab 页面后,缓存将失效。
1.3.Disk Cache
  • Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。

  • 在所有浏览器缓存中,Disk Cache 覆盖面基本是最大的。它会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。并且即使在跨站点的情况下,相同地址的资源一旦被硬盘缓存下来,就不会再次去请求数据。绝大部分的缓存都来自 Disk Cache,关于 HTTP 的协议头中的缓存字段,我们会在下文进行详细介绍。

1.4.Push Cache

  • Push Cache(推送缓存)是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使用。它只在会话(Session)中存在。
    详细链接:HTTP/2 push is tougher than I thought

2、HTTP 缓存

缓存分为强缓存和协商缓存。在命中强缓存失败的情况下,才会走协商缓存。

2.1强缓存

  • 2.1.1强缓存的特征
    • 利用 http 头中的 ExpiresCache-Control 两个字段来控制的,若命中则直接从缓存中获取资源,不会再与服务端发生通信。
  • 2.1.2强缓存的实现方式
    • 2.1.2.1 expires (http1.0)
      当服务器返回响应时,会在 Response Headers 中写入 expires 字段。当再次请求资源,如果本地时间小于 expires 时间,就会直接取缓存中的资源。expires: Wed, 11 Sep 2019 16:12:18 GMT
    • 2.1.2.2 Cache-Control (http1.1)
      Cache-Controlexpires 同时出现时,以 Cache-Control 为准。
      详情如下:
      在这里插入图片描述
      • public:既可以被浏览器缓存,也可以被代理服务器缓存
      • private:该资源只能被浏览器缓存(默认值)
      • no-cache: 绕开了浏览器,每次请求不再询问浏览器缓存情况,而直接向服务端去确认该资源是否过期
      • no-store:在 no-cache 的基础上,服务端的缓存也呗绕开,即直接向服务端发送请求、并下载完整的响应
      • max-age:表示缓存内容将在xxx秒后失效
      • s-maxage(单位为s):同max-age作用一样,只在代理服务器中生效(比如CDN缓存)

注:s-maxage的优先级高于max-age。如果存在s-maxage,则会覆盖掉max-ageExpires header

2.2协商缓存

协商缓存依赖于服务端与浏览器之间的通信。
协商缓存机制下,浏览器需要向服务器去询问缓存的相关信息,进而判断是重新发起请求、下载完整的响应,还是从本地获取缓存的资源。
如果服务端提示缓存资源未改动(Not Modified),资源会被重定向到浏览器缓存(即304状态码)

  • 2.2.1协商缓存的实现方式
    • 2.2.1.1Last-Modified (一个时间戳)
    1. 如果我们启用了协商缓存,它会在首次请求时随着 Response Headers 返回:Last-Modified: Fri Sep 18 2020 10:01:04 GMT+0800
    2. 随后每次请求,会带上 If-Modified-Since 字段,其值正是上一次请求返回的 last-modified 值If-Modified-Since: Fri Sep 18 2020 10:01:04 GMT+0800
    3. 服务器会比对请求中的If-Modified-Since和服务器上的Last-Modified是否一致
      如果发生了变化,就会返回一个完整的响应内容,并在 Response Headers 中添加新的 Last-Modified 值
      否则,返回的 304 响应,Response Headers 不会再添加 Last-Modified 字段。
    • 2.2.1.2Etag (根据每个文件内容生成的类似hash值的唯一标识字符串)
    1. Etag 是由服务器为每个资源生成的唯一的标识字符串,只要文件内容不同,它们对应的 Etag 就是不同的,反之亦然。因此 Etag 能够精准地感知文件的变化。
    2. 和Last-Modified类似:首次请求,Response Headers 返回:ETag: W/“2a3b-1602480f459”
    3. 再次请求,请求头中携带:If-None-Match: W/“2a3b-1602480f459”
    4. 服务器根据请求头中的ETag和服务器上的If-None-Matchhe否相等来进行相应的缓存策略或者返回新内容

3.HTTP 缓存决策指南

在这里插入图片描述

  • 当我们的资源内容不可复用时,直接为 Cache-Control 设置 no-store,拒绝一切形式的缓存;
  • 否则考虑是否每次都需要向服务器进行缓存有效确认,如果需要,那么设 Cache-Control 的值为 no-cache;
  • 否则考虑该资源是否可以被代理服务器缓存,根据其结果决定是设置为 private 还是 public;
  • 然后考虑该资源的过期时间,设置对应的 max-age 和 s-maxage 值;
  • 最后,配置协商缓存需要用到的 Etag、Last-Modified 等参数。

4.缓存策略的不同触发情景

用户在浏览器如何操作时,对应触发的缓存策略主要有 3 种:

  • 打开网页,地址栏输入地址: 查找 disk cache 中是否有匹配。如有则使用;如没有则发送网络请求。
  • 普通刷新 (F5):因为 TAB 并没有关闭,因此 memory cache 是可用的,会被优先使用(如果匹配的话)。其次才是 disk
    cache。
  • 强制刷新 (Ctrl + F5):浏览器不使用缓存,因此发送的请求头部均带有 Cache-control:
    no-cache(为了兼容,还带了 Pragma: no-cache),服务器直接返回 200 和最新内容。

参考:
Http缓存机制与原理
HTTP缓存机制
一张图理解Http缓存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值