1 Star 2 Fork 0

神奇码农 / WebInterview

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
HTTP2&HTTP缓存.md 12.88 KB
一键复制 编辑 原始数据 按行查看 历史
unknown 提交于 2021-03-05 20:08 . 拆分

HTTP2&HTTP缓存

1.http/2项目设定目标

1.页面加载时间 (PLT) 减少 50%。

2.无需网站作者修改任何内容。

3.将部署复杂性降至最低,无需变更网络基础设施。

4.与开源社区合作开发此新协议。

5.收集真实性能数据,验证实验性协议是否有效。

2.http/2特性

  1. 二进制分帧层

HTTP/2 所有性能增强的核心在于新的二进制分帧层,它定义了如何封装 HTTP 消息并在客户端与服务器之间传输。

  1. 多路复用(请求与响应复用)

HTTP/2 中新的二进制分帧层突破了这些限制,实现了完整的请求和响应复用:客户端和服务器可以将 HTTP 消息分解为互不依赖的帧,然后交错发送,最后再在另一端把它们重新组装起来。

  1. 数据流优先级

将 HTTP 消息分解为很多独立的帧之后,我们就可以复用多个数据流中的帧,客户端和服务器交错发送和传输这些帧的顺序就成为关键的性能决定因素。 为了做到这一点,HTTP/2 标准允许每个数据流都有一个关联的权重和依赖关系:

  • 可以向每个数据流分配一个介于 1 至 256 之间的整数。
  • 每个数据流与其他数据流之间可以存在显式依赖关系。
  1. 每个来源一个连接

每个数据流都拆分成很多帧,而这些帧可以交错,还可以分别设定优先级。 因此,所有 HTTP/2 连接都是永久的,而且仅需要每个来源一个连接,随之带来诸多性能优势。

  1. 流控制

流控制是一种阻止发送方向接收方发送大量数据的机制,以免超出后者的需求或处理能力:发送方可能非常繁忙、处于较高的负载之下,也可能仅仅希望为特定数据流分配固定量的资源。

  1. 服务器推送

HTTP/2 新增的另一个强大的新功能是,服务器可以对一个客户端请求发送多个响应。 换句话说,除了对最初请求的响应外,服务器还可以向客户端推送额外资源,而无需客户端明确地请求。

7.标头压缩

每个 HTTP 传输都承载一组标头,这些标头说明了传输的资源及其属性。 HTTP/2 使用 HPACK 压缩格式压缩请求和响应标头元数据,这种格式采用两种简单但是强大的技术:

  • 这种格式支持通过静态霍夫曼代码对传输的标头字段进行编码,从而减小了各个传输的大小。
  • 这种格式要求客户端和服务器同时维护和更新一个包含之前见过的标头字段的索引列表(换句话说,它可以建立一个共享的压缩上下文),此列表随后会用作参考,对之前传输的值进行有效编码。

3.什么是缓存?又有什么用?

定义:缓存是一种保存资源副本并在下次请求时直接使用该副本的技术。

作用:

1.可以显著提高网站和应用程序的性能。

2.减少了等待时间和网络流量

3.减少了显示资源表示形式所需的时间。

4.是页面更加响应性。

5.缓解服务器端压力,提升性能。

4.你知道有哪些缓存方式吗?

1.浏览器缓存

2.代理缓存

3.网关缓存

4.CDN缓存

5.反向代理缓存

5.缓存位置

  • Service Worker Service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。

  • Memory Cache 读取高效,但是持续性很短,一旦关闭 Tab 页面,内存中的缓存也就被释放了。

  • Disk Cache 读取速度慢,容量和存储时效性上有优势,

  • Push Cache 读取速度慢,容量和存储时效性上有优势,

6.http缓存怎样生效的?

http缓存分为强制缓存和协商缓存

  1. 强制缓存 强制缓存就是文件直接从缓存中获取,不需要发送请求

  2. 协商缓存 协商缓存意思是文件已经被缓存了,但是否从缓存中读取是需要和服务器进行协商,具体如何协商要看请求头/响应头的字段设置。 协商缓存还是会发送请求的。

  3. 强缓存-Cache-Control Cache-Control 通用消息头字段,被用于在http请求和响应中,通过指定指令来实现缓存机制。

  4. 缓存请求指令

Cache-Control: max-age=<seconds>
Cache-Control: max-stale[=<seconds>]
Cache-Control: min-fresh=<seconds>
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: only-if-cached
  1. 缓存响应指令
Cache-control: must-revalidate
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: public
Cache-control: private
Cache-control: proxy-revalidate
Cache-Control: max-age=<seconds>
Cache-control: s-maxage=<seconds>
  1. 指令解释

4.协商缓存生效过程

  1. 浏览器第一次请求:

7.HTTP2的伪头字段

  • 伪头部字段是http2内置的几个特殊的以”:”开始的 key,用于替代HTTP/1.x中请求行/响应行中的信 息,比如请求方法,响应状态码等
  1. :method 目标URL模式部分(请求)
  2. :scheme 目标URL模式部分(请求)
  3. :authority 目标RUL认证部分(请求)
  4. :path 目标URL的路径和查询部分(绝对路径 产生式和一个跟着"?"字符的查询产生式)。 (请求)
  5. :status 响应头中的HTTP状态码部分(响应)

8.HTTP 2:服务器推送

  • HTTP 2 新增的另一个强大的新功能是,服务器可以对一个客户端请求发送多个响 应。 换句话说,除了对最初请求的响应外,服务器还可以向客户端推送额外资源,而无需客户端明确地请求。
  • HTTP 2 打破了严格的请求-响应语义,支持一对多和服务器发起的推送工作流
  • 服务器已经知道客户端下一步要请求什么资源,这时候服务器推送即可派上用场。
  • 推送资源可以进行以下处理:
  1. 由客户端缓存
  2. 在不同页面之间重用
  3. 与其他资源一起复用
  4. 由服务器设定优先级
  5. 被客户端拒绝

9.队首阻塞问题

  • HTTP/1.1 和 HTTP/2 都存在队头阻塞问题(Head of line blocking)
  • HTTP/1.1 的队头阻塞。一个 TCP 连接同时传输 10 个请求,其中第 1、2、3 个请求已被客户端接收,但第 4 个请求丢失,那么后面第 5 - 10 个请求都被阻塞,需要等第 4 个请求处理完毕才能被处理,这样 就浪费了带宽资源。
  • HTTP/2 的多路复用虽然可以解决“请求”这个粒度的阻塞,但 HTTP/2 的基础 TCP 协议本身却也存在着队头阻塞的问题。
  • 由于 HTTP/2 必须使用 HTTPS,而 HTTPS 使用的 TLS 协议也存在队 头阻塞问题。
  • 队头阻塞会导致 HTTP/2 在更容易丢包的弱网络环境下比 HTTP/1.1 更慢。
  • 那 QUIC 解决队头阻塞问题的的方法:
  1. QUIC 的传输单元是 Packet,加密单元也是 Packet,整个加密、 传输、解密都基于 Packet,这样就能避免 TLS 的队头阻塞问题;
  2. QUIC 基于 UDP,UDP 的数据包在接收端没有处理顺序,即使中间 丢失一个包,也不会阻塞整条连接,其他的资源会被正常处理。

10.Transport头域

  • Connection: close(告诉WEB服务器或者代理服务器,在完成本次请求的响应后,断开连接,不要等待本次连接的后续请求了) keepalive(告诉WEB服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求)
  • Host:指定被请求资源的Internet主机和端口号

11.时效缓存(强制缓存)

Cache-Control (低版本浏览器用的是Expires,了解即可)

是最重要的规则。常见的取值有private、public、no-cache、max-age,no-store,默认为private。

private: 客户端可以缓存

public: 客户端和代理服务器都可缓存(前端的同学,可以认为public和private是一样的)

max-age=xxx: 缓存的内容将在 xxx 秒后失效

no-cache: 需要使用对比缓存来验证缓存数据

no-store: 所有内容都不会缓存,强制缓存,对比缓存都不会触发(对于前端开发来说,缓存越多越好,so...基本上和它说886)

12.非时效缓存(对比缓存,用的是标识):

他用的不是时效时间max-age

第一次请求的时候,返回给客户端数据和缓存的信息,也就是一个特定的缓存标识

客户端把这个缓存标识放到缓存数据库

再次请求时 客户端先把缓存标识也一起发给服务端,进行对比

客户端将备份的缓存标识发送给服务器,服务器根据缓存标识进行判断,判断成功后,返回304状态码,通知客户端比较成功,可以使用缓存数据。

13.两种缓存标识

Etag (唯一标识)优先级更高

Last-Modified/If-Modified-Since 返回给客户端最后这个资源的修改时间,优先级没有Etag高

对比缓存标识生效不生效时,状态码200,服务端返回body和header

在对比缓存标识生效时,状态码为304,并且报文大小和请求时间大大减少。

原因是,服务端在进行标识比较后,只返回header部分,通过状态码通知客户端使用缓存,不再需要将报文主体部分返回给客户端。

14.Service Worker

比如页面引入了一个 JQuery,对于页面来说这个脚本就是一个工具库,基本上是不会发生变化的,对于这种资源可以将它的缓存时间设置得长一点,比如如下这个地址的脚本:

是一个注册在指定源和路径下的事件驱动 worker;特点是:

  • 运行在 worker 上下文,因此它不能访问 DOM
  • 独立于主线程之外,不会造成阻塞;
  • 设计完全异步,所以同步 API(如 XHRlocalStorage )不能在 Service Worker 中使用;
  • 最后处于安全考虑,必须在 HTTPS 环境下才可以使用;

说了这么多特点,那它和缓存有啥关系?其实它有一个功能就是离线缓存:Service Worker Cache;区别于浏览器内部的 memory cachedisk cache,它允许我们自己去操控缓存,具体操作过程可以参看 Using_Service_Workers;通过 Service Worker 设置的缓存会出现在浏览器开发者工具 Application 面板下的 Cache Storage 中。

15.memory cache

是浏览器内存中的缓存,相比于 disk cache 它的特点是读取速度快,但容量小,且时效性短,一旦浏览器 tab 页关闭,memory cache 就将被清空。memory cache 会自动缓存所有资源嘛?答案肯定是否定的,当 HTTP 头设置了 Cache-Control: no-store 的时候或者浏览器设置了 Disabled cache 就无法把资源存入内存了,其实也无法存入硬盘。当从 memory cache 中查找缓存的时候,不仅仅会去匹配资源的 URL,还会看其 Content-type 是否相同。

16.disk cache

也叫 HTTP cache 是存在硬盘中的缓存,根据 HTTP 头部的各类字段进行判定资源的缓存规则,比如是否可以缓存,什么时候过期,过期之后需要重新发起请求吗?相比于 memory cachedisk cache 拥有存储空间时间长等优点,网站中的绝大多数资源都是存在 disk cache 中的。

浏览器如何判断一个资源是存入内存还是硬盘呢?关于这个问题,网上说法不一,不过比较靠谱的观点是:对于大文件大概率会存入硬盘中;当前系统内存使用率高的话,文件优先存入硬盘。

缓存按照缓存位置划分,其实还有一个 HTTP/2 的内容 push cache,由于目前国内对 HTTP/2 应用还不广泛,且网上对 push cache 的知识还不齐全,所以本篇不打算介绍这块,感兴趣的可以阅读这篇文章:HTTP/2 push is tougher than I thought

参考链接

https://juejin.cn/post/6844904135137951758

https://blog.csdn.net/zouzixuan/article/details/84677548

https://juejin.cn/post/6911482888491892749

1
https://gitee.com/WebInterviewHub/WebInterview.git
git@gitee.com:WebInterviewHub/WebInterview.git
WebInterviewHub
WebInterview
WebInterview
master

搜索帮助