强缓存 200 from cache 直接从本地缓存中获取响应

  1. PragmaHTTP1.0时代的遗留产物, 该字段被设置为 no-cache 时, 会告知浏览器禁用本地缓存, 即每次都向服务器发送请求
  2. ExpiresHTTP1.0时代用来启用本地缓存的字段, expires 值对应一个形如 Thu, 31 Dec 2037 23:55:55 GMT 的格林威治时间, 如果还没有到该时刻, 标明缓存有效, 无需发送请求受限于本地时间
  3. Cache-ControlHTTP1.1针对 Expires 问题的解决方案, 使用 Cache-Control 告诉浏览器缓存过期的时间间隔而不是时刻
    • public: 可以被所有用户缓存,包括终端和CDN等中间代理服务器
    • private: 只能被终端浏览器缓存
    • no-cache: 不允许直接使用本地缓存, 先发起请求和服务器协商
    • no-store: 禁止浏览器缓存响应, 不使用强缓存和协商缓存
    • max-age = 30: 本地缓存 30s

优先级:
Pragma > Cache-Control > Expires

协商缓存 304 Not Modified

  • Last-Modified通知浏览器资源的最后修改时间
  • If-Modified-Since得到资源的最后修改时间后, 浏览器会将这个信息通过 If-Modified-Since 提交到服务器做检查

HTTP1.1推出: 文件的指纹标识符, 如果文件内容修改, 指纹会改变

  • ETagW/“5fc-15cc33b8d98”
  • If-None-MatchW/“5fc-15cc33b8d98”

优先级:
ETag > Last-Modified

DNS 域名解析

  1. 首先会在本地缓存中查询 IP(浏览器缓存 系统缓存 路由缓存)
  2. 再去系统配置的 DNS 服务器中查询(运营商各级缓存 traceRoute)
  3. 还没找到则会去 DNS 根服务器查询
    • 找到 com 这个一级域名的服务器
    • 然后去该一级域名服务器查询 daidaibo二级域名
  4. 接下来三级域名的查询是自己配置的,可以给 www 这个域名配置一个 IP,也可以给别的三级域名配置一个 IP

以上是 DNS迭代查询方式,还有一种是递归查询

  • 迭代查询是由客户端去做请求
  • 递归查询是由系统配置的 DNS 服务器做请求,得到结果后将数据返回给客户端

DNS 是基于 UDP 做的查询

TCP 三次握手

  • 应用层会下发数据给传输层,这里 TCP 协议会指明两端的端口号
  • 然后下发给网络层,网络层中的 IP 协议会确定 IP 地址,并且指示了数据传输中如何跳转路由器
  • 接着包会再被封装到数据链路层的数据帧结构中
  • 最后就是物理层面的传输了

当 TCP 握手结束后就会进行 TLS 握手,然后就开始正式的传输数据

CDN 静态加速、Nginx 负载均衡

HTTP 状态码

4xx 5xx

报错

3xx

重定向,这里会有个重定向计数器,避免过多次的重定向,超过次数也会报错

200 ok 没有用到缓存

  • 服务端会响应一个 HTML 文件
  • 浏览器开始解析文件,如果是 gzip 格式会先解压,然后通过文件的编码格式去解码文件

HTML 文件

  1. 网络传输过程中的二进制数据
  2. 浏览器接收后转码成字符串
  3. 再通过词法parse为Token
  4. Token紧接着构建成Node
  5. Node之间关联生成DOM树

字节数据 -> 字符串 -> Token -> Node -> DOM Tree

CSS 文件

字节数据 -> 字符串 -> Token -> Node -> CSSOM Tree

阻塞渲染

HTML

扁平化层级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- DNS 预解析 -->
<link rel="dns-prefetch" href="//daidaibo.com">

<!-- TCP 预连接 -->
<link rel="preconnect" href="//daidaibo.com">

<!-- 预渲染 -->
<link rel="prerender" href="//daidaibo.com">

<!-- 预加载 表示资源在当前页面使用,浏览器会优先加载 -->
<link rel="preload" href="style.css" as="style">
<link rel="preload" href="main.js" as="script">

<!-- 预获取 表示资源可能在交互的界面使用,浏览器将在空闲时加载 -->
<link rel="prefetch" href="other.js" as="script">

CSS

优化选择器从右往左解析选择器

JS

  • <script defer src=”xxx.js”>异步并行下载,HTML 解析完成后执行,执行的顺序按声明顺序来
  • <script async src=”xxx.js”>异步并行下载,加载完立即执行,不适用于有先后依赖关系的 JS 文件

Attachment

Layout 布局

DOM Tree + CSSOM Tree = Render Tree

浏览器调用 GPU 绘制,合成图层,将内容显示在屏幕上

Render Tree 边下载边解析边渲染

继续戳 👈

Reflow 回流 / 重排

  • 页面首次渲染
  • 浏览器窗口大小发生变化
  • 元素尺寸或位置发生变化
  • 字体大小变化
  • 在页面中添加或删除某个元素

Repaint 重绘

重排必然会引起重绘

  1. 集中修改样式,或直接使用 class
  2. DOM 操作前先使用 display: none 脱离文档流
  3. 使用 BFC,不影响外部的元素
  4. 对于频繁触发的操作(resize scroll 等)使用节流防抖
  5. 使用 createDocumentFragment 进行批量 DOM 操作
  6. 优化动画,使用 requestAnimationFrame 或者 CSS3(GPU 加速)
    • transform
    • opacity
  7. 将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点
    • will-change
    • video、iframe 标签

总结:DNS解析–TCP连接–HTTP请求–Waiting Response–Parse资源–Render页面

OSI 参考模型

名称 说明 设备 协议
应用层 为应用程序提供服务,面向用户
报文
计算机 HTTP、Socket、Telnet、SSH、FTP
SMTP、SNMP、POP3、DNS
表示层 数据格式转换、数据编码、数据加密、解压缩
会话层 建立、管理和维护会话,寻址,Session层流量控制,错误控制 SSL/TLS
传输层 建立、管理和维护端到端的连接,传输差错校验,流量拥塞控制
数据段
防火墙 TCP、UDP
网络层 IP选址及路由选择
数据包
路由器 IP
数据链路层 提供介质访问和链路管理
数据帧
交换机 ARP、RARP
物理层 利用传输介质提供物理连接
比特流
网 卡

TCP/IP 协议

名称 协议
应用层 HTTP
传输层 TCP
网际层 IP
网络接口层 以太网驱动程序

TCP 有状态

  • TCP 传输控制协议 面向连接可靠传输
    1. 拥塞控制 流量控制
    2. 一对一
    3. 面向字节流
    4. 首部 最少20字节 最多60字节
    5. 适用于稳定性高的场景:文件传输
  • UDP 用户数据协议 无连接的不可靠传输
    1. 一对一、一对多、多对多
    2. 面向IP报文
    3. 首部开销8字节
    4. 适用于时效性高的场景:音视频会议

三次握手

Client Service
hello
hello
ok

保证双方都可以正常地发送接收请求

四次挥手

Client Service
我好了
等一等
我也好了
拜拜

HTTP 无状态

HTTP 报文

  1. 请求报文: 请求行 请求头 空行 请求体
    • 请求行 请求方法 + URL + 协议版本 + 回车符 换行符
    • GET /index.html HTTP/1.1
  2. 响应报文: 响应行 响应头 空行 响应体
    • 状态行 协议版本 + 状态码 + 状态码短语 + 回车符 换行符
    • HTTP/1.1 200 OK

HTTP 状态码

  • 1xx 消息
  • 2xx 成功
    1. 200 OK 请求成功,表示从客户端发来的请求在服务器端被正确处理
    2. 201 Created 创建成功,请求已经被实现,而且有一个新的资源已经依据请求的需要而建立
    3. 202 Accepted 更新成功,请求已接受,但是还没执行,不保证完成请求
    4. 204 No content 删除成功,表示请求成功,但响应报文不含实体的主体部分
    5. 205 Reset Content,表示请求成功,但响应报文不含实体的主体部分,但是与 204 响应不同在于要求请求方重置内容
    6. 206 Partial Content,进行范围请求
  • 3xx 重定向
    1. 301 Moved Permanently,永久性重定向,表示资源已被分配了新的 URL
    2. 302 Found,临时性重定向,表示资源临时被分配了新的 URLhttp1.0
    3. 303 See Other,临时重定向,和 302 含义类似,但是期望客户端使用 GET 方法向新的地址发出请求http1.1
    4. 304 Not Modified 协商缓存
    5. 307 Temporary Redirect,临时重定向,和 302 含义类似,但是期望客户端保持请求方法不变向新的地址发出请求http1.1
  • 4xx 客户端错误
    1. 400 Bad Request,请求报文存在语法错误
    2. 401 Unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息
    3. 403 Forbidden,表示对请求资源的访问被服务器拒绝
    4. 404 Not Found,表示在服务器上没有找到请求的资源
    5. 408 Request Timeout,客户端请求超时
    6. 409 Conflict,请求的资源可能引起冲突
    7. 413 Required Length Too Large,上传的文件体积太大
  • 5xx 服务器错误
    1. 500 Internal Sever Error,内部服务器错误
    2. 501 Not Implemented,请求超出服务器能力范围,例如服务器不支持当前请求所需要的某个功能,或者请求是服务器不支持的某个方法
    3. 503 Service Unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求
    4. 505 Http Version Not Supported,服务器不支持,或者拒绝支持在请求中使用的 HTTP 版本

HTTP 1.0

最基础的 HTTP 协议

HTTP 1.1

  1. 引入更多的缓存策略,如 cache-control ETag
  2. 长链接,默认开启 Connection: keep-alive,减少 TCP 重连次数(并发多个请求需要多个 TCP 连接,限制6~8个)
    • 管线化,请求与请求间并行,但响应仍是串行的
    • 只有 GET 和 Head 请求可以管线化,而 POST 则有所限制
  3. 断点续传,状态码 206
  4. 新增 Method PUT DELETE 等,可以设计 Restful API

HTTP 2.0

  1. 二进制分帧 👈核心
    • 在 HTTP 1.x 中,数据以文本的格式进行传输,解析起来比较低效
    • HTTP 2.0 在传输消息时,会将消息划分为更小的消息和,然后再对其采取二进制格式的编码,确保高效的解析
  2. Header 压缩,只发送差异数据,以减少体积
  3. 多路复用
    • 实现真正的并行请求(管线化的问题)
    • 同域名只通过一个 TCP 连接就可以传输所有的请求数据,也间接实现全速传输,毕竟新开一个 TCP 连接都需要慢启动
    • HTTP/1 浏览器限制了一个域名下同时请求的数量,雪碧图、Base64、使用多个域名等优化将变得多余
  4. 服务器端推送
    • 服务端可以在发送⻚面 HTML 时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。例如服务端可以主动把 JS 和 CSS 文件推送给客户端,而不需要客户端解析 HTML 时再发送这些请求
    • 服务端可以主动推送,客户端也有权利选择是否接收。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送 RST_STREAM 帧来拒收。主动推送也遵守同源策略,服务器不会随便推送第三方资源给客户端

HTTP 3.0

HTTP/2 使用了多路复用,一般来说同一域名下只需要使用一个 TCP 连接。当这个连接中出现了丢包的情况,那就会导致 HTTP/2 的表现情况反倒不如 HTTP/1 了。

在出现丢包的情况下,整个 TCP 都要开始等待重传,也就导致了后面的所有数据都被阻塞了。

但是对于 HTTP/1 来说,可以开启多个 TCP 连接,出现这种情况反倒只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。

HTTPS

HTTP + SSL/TLS = HTTPS
SSL 被标准化改名为 TLS

  • HTTPS 还是通过了 HTTP 来传输信息,但是信息通过 TLS 协议进行了加密
  • TLS 协议位于传输层之上,应用层之下的会话层
  • 在 TLS 中使用了两种加密技术,分别为:对称加密非对称加密