Web缓存机制之http缓存

啥是缓存?

当从客户端向服务端获取资源,需要建立链接,资源传输等一系列消耗,为了方便下次获取的资源更快,性能开销更小,是不是可以把第一次获取的资源储存起来,下次直接拿呢,没错这就是缓存。

存哪了?

好了知道什么是缓存了,那么缓存具体存哪了?

Service Worker

W3C 组织早在 2014 年 5 月就提出过 Service Worker 这样的一个 HTML5 API ,主要用来做持久的离线缓存。service worker是浏览器的一个高级特性,本质是一个web worker,是独立于网页运行的脚本。 web worker这个api被造出来时,就是为了解放主线程。

Memory Cache

内存缓存,常见于强缓存

Disk Cache

磁盘缓存,常见于强缓存

缓存类型有哪些?

强缓存

浏览器强制缓存服务端提供的资源

在web应用中,时常可以status code: 200(from memory cache)或者status code: 200(from disk cache),没错这就是强缓存的实际应用。那么这时候聪明的你一定思考过,这两种方式有什么区别呢?

memory cache实际上disk cache 快的多。如果从远程 web 服务器直接提取访问文件可能500毫秒,那么磁盘访问可能需要10-20毫秒,而内存访问只需要100纳秒

那么问题又来了,如果我们如何控制是从memory还是从disk缓存获取呢。

看个栗子

第一次获取资源之后,再次获取从缓存中获取资源(memory cache)刷新同样。

关闭浏览器从新打开,观察该资源获取方式,从memory cache变成了disk cache

这里原因是什么?答案就是浏览器来决定使用哪种方式获取资源。这里引发了两外一个问题,浏览器缓存原理。

 

浏览器缓存原理

获取资源首先从memory中获取如果有直接加载目标资源。

如果memory没有,选择从disk获取,如果有直接加载

如果disk也没有,那么就进行网络请求

加载到的资源缓存到硬盘和内存

所以加载优先级就是memory cache大于disk cache,毕竟内存更快嘛~

流程图:

 

协商缓存

协商缓存,是在缓存过期的情况下,客户端和服务端协商,确认客户端缓存是否需要更新

  • 使用资源最后修改的日期来判断(http1.0)
  • 使用令牌(ETag)标识来识别(http1.1)

强缓存协商缓存优先级

同时设置了强缓存跟协商缓存,那么优先级是什么呢?

首先下结论:强缓存优先级大于协商缓存

回顾协商缓存,在缓存过期的情况下,客户端和服务端协商,确认客户端缓存是否需要更新。这个缓存过期指定就是强缓存。通常在系统使用缓存机制的时候,我们在强缓存或者协商缓存之间选择其中一种。

看个栗子

一个status code是304的请求

响应的时候多个一个Etag标签作为令牌

服务器If-None-Match来与Etag做对比

 

流程图

 

好了到这里协商缓存是不是已经了解了呢~

那么如何在实践中设置缓存类型呢~

Cache-Control(http1.1版本)

  • no-store
  • no-cache
  • max-age=x
  • s-maxage=x
  • public
  • private
  • must-revalidate

no-store

禁止使用缓存。带有no-store的响应不会被缓存到任意的磁盘或者内存里。p.s.通常没有这么用的。

no-cache

协商缓存使用场景

协商缓存使用场景

no-cache等同于max-age=0

告诉浏览器、缓存服务器,不管本地副本是否过期,使用资源副本前,一定要到源服务器进行副本有效性校验。校验有效性?没错通常这么设置是为了使用协商缓存。

http:1.1

请求头: If-None-Match

响应头: Etag

http:1.0

请求头: If-Modified-since:Date

响应头: Last-Modified:Date

max-age=x

强缓存使用场景(max-age=0除外

缓存内容将在x秒后失效

s-maxage=x

考虑到max-age适用于所有缓存,而s-maxage仅适用于共享缓存(代理、网关缓存、CDN等等)

public/private

private

您不允许代理缓存通过它们传播的数据。 最后,这一切归结为您发送的页面/文件中包含的数据。

例如,您的ISP可能在您和Internet之间有一个不可见的代理,即缓存网页以减少所需的带宽量并降低成本。 通过使用cache-control:private,您指定它不应该缓存页面(但允许最终用户这样做)

public

使用cache-control:public,则表示每个人都可以缓存该页面,因此代理将保留一个副本。

总结:如果每个人都可以访问(例如,此页面中的徽标)缓存控制:public可能会更好,因为更多的人缓存它,您需要的带宽越少。 如果它是与所连接的用户相关的(例如,此页面中的HTML包含我的用户名,所以对其他人来说并不有用)cache-control:private将会更好,因为代理将缓存数据这不会被其他用户请求,并且他们也可能会保留不想保存在不信任的服务器中的数据。

must-revalidate

告诉浏览器、缓存服务器,本地副本过期前,可以使用本地副本;本地副本一旦过期,必须去源服务器进行有效性校验。must-revalidate生效的场景还有一个大前提,

那就是 HTTP 规范是允许客户端在某些特殊情况下直接使用过期缓存的。

 

后续会补充所有与http请求相关的知识点,如果哪里阐述或者理解不对希望指正,共同进步~

posted @ 2023-06-05 00:29  漠然0408丶  阅读(165)  评论(0编辑  收藏  举报