前端HTTP缓存你真的了解吗?强缓存?协商缓存?启发式缓存?

背景

HTTP缓存,一个老生常谈的话题,一个高频出现的面试题,一个强缓存、协商缓存简单几句话就能概括的缓存机制,一个所有前端页面都需要用到却又极少被关注的功能。它远比想象中更强大,更智慧,更重要。本文将和大家一起感受HTTP缓存的智慧和魅力,一起彻彻底底的搞清楚HTTP缓存的机制,一起使用它来提升咱们的项目性能。

HTTP缓存是客户端和服务端通信的一种缓存,可以将网页访问产生的数据缓存到内存或本地。合理利用这一缓存可以提升资源重复利用率,减少网络带宽,降低服务器压力,提升客户端响应速度。

请求头&响应头

在介绍HTTP缓存之前,我们先来了解一下请求头和响应头与HTTP缓存之间的关系。如下图所示,一个请求通常会包含一个响应头(Response Headers),一个请求头(Request Headers),可以看到请求头和响应头中都包含了很多字段,这些字段称为首部字段,其中有一些就是和HTTP缓存相关的,后面我会将相关字段都提取出来。

image.png

HTTP缓存总的来说可以分为两大类,一类是强缓存,一类是协商缓存。强缓存和协商缓存的设置,都存放于请求头和响应头中的首部字段,相关的字段我做成了思维导图。可以看到,和HTTP缓存相关的字段还是比较多的,初次看到可能一头雾水,不用担心,后面在讲强缓存和协商缓存部分的时候,我会一一解释各字段的含义。

强缓存

我们第一次打开某个网站,加载速度会比较慢,再次访问时能明显感觉到加载速度较第一次更快速,这就是强缓存在起作用。画两张时序图描述一下强缓存生效和未生效的流程。

  • 强缓存未生效

  • 强缓存生效

说了这么多,我们打开浏览器实操一下,看一下在浏览器中强缓存生效和失效的实际表现。

首次加载,强缓存未生效

我们清除一下缓存(Chorm浏览器打开开发者工具后,刷新图标右键,选择清空缓存并硬性重新加载)模拟首次加载,可以在network面板看到资源的加载情况。我们重点关注一下Size和Time列的数据,Size列表示从服务器获取资源的大小,Time列表示资源加载耗时,可以看到第一次加载时,几乎每个资源都是从服务器获取,所以打开速度会受到影响,资源加载总耗时3.34s。

image.png

第二次加载,强缓存生效

第二次访问该网站的时候,大多数资源的Size都变成了 Memory cache 和 Disk cache , 并且加载时间Time也极大的缩短,资源加载总耗时也由之前的3.34s变为了1.98s。

image.png

首部字段解析

从上文中可以看出,合理设置强缓存可以减少不必要的服务端请求,提升网页打开速度。设置强缓存的奥秘就在于请求头和响应头中的首部字段,一起来看一下和强缓存相关的首部字段吧。

  • Expires 首部字段是 HTTP/1.0 中定义缓存的字段,其给出了缓存过期的绝对时间,即在此时间之后,响应资源过期。

  • Cache-Control 首部字段是 HTTP/1.1 中定义缓存的字段,其用于控制缓存的行为,可以组合使用多种指令,多个指令之间可以通过 “,” 分隔,常用的指令有:max-age、s-maxage、public/private、no-cache/no store 等。

    • max-age: 给出了缓存的相对时间,单位为秒,即获得响应之后多少秒后过期,和Expires同时出现时,max-age优先级更高。
    • s-maxage:对公共缓存服务器生效,表示该资源在公共服务器中缓存的相对时间。如果存在公共缓存服务器,浏览器缓存失效后,会先请求公共缓存服务器,公共缓存服务器失效后会重新请求资源服务器更新公共缓存服务器中的资源,然后返回给浏览器。
    • public:表示可以被任何节点缓存,包括客户端和公共缓存服务器。
    • private:表示该资源只能被客户端(浏览器)缓存。
    • no-cache :表示客户端每次使用缓存资源前必须向服务器确认其有效性。
    • no-store :表示不缓存资源。

下图展示了一个缓存有效期为一年的资源,31536000秒/60*60/24 = 365 天

image.png

协商缓存

了解完强缓存后,接下来继续聊聊协商缓存,协商缓存和强缓存并不是两个相对独立的概念,两者有着密不可分的联系。协商缓存是在强缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识来决定是否使用缓存。还是用时序图来描述一下协商缓存生效、未生效的流程。

  • 协商缓存未生效

  • 协商缓存生效

首部字段解析

和协商缓存相关的首部字段主要有4个,Last-Modified 与 If-Modified-Since,Etag 与 If-None-Match。

  • Last-Modified:代表资源最后修改时间,存在服务端返回的响应头。
  • If-Modified-Since:存在客户端请求头,值为上次存储的Last-Modified,判断资源是否过期。
  • Etag: 代表资源的唯一标识,存在服务端返回的响应头,Etag优先级高于Last-Modified。
  • if-None-Match: 存在客户端请求头,值为上次存储的Etag,判断资源是否过期。

彩蛋:启发式缓存

在强缓存的章节中,我们了解到了缓存有效期由ExpiresCache-Control中的max-age来决定的,那么如果响应头中不存在这两个字段,缓存的有效期怎么计算呢?浏览器还会走强缓存吗?答案是肯定的,这就是我们要现在要了解的启发式缓存

当报头中没有用来确定强缓存时间的字段时,浏览器会触发启发式缓存,缓存有效期计算公式:**(date - last-modified ) * 10%,**取响应报头中 date 与 last-modified 值之差的百分之十作为缓存时间。启发式缓存比较容易忽略,不了解启发式缓存可能会因为这种默认的缓存方式而掉入坑里,但一旦你了解了浏览器启发式缓存的机制,很多问题都可以得到解决。

总结

本文首先介绍了和HTTP缓存息息相关的请求头和响应头,接下来引出了两种缓存方式,强缓存协商缓存,并介绍了他们的运行流程以及关键首部字段,最后提出了很容易忽略的启发式缓存,希望本文能够对你有帮助。


原文链接:https://juejin.cn/post/7264597522030329910
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值