You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Service Worker 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。使用 Service Worker的话,传输协议必须为 HTTPS。因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全。Service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。
Service Worker 实现缓存功能一般分为三个步骤:首先需要先注册 Service Worker,然后监听到 install 事件以后就可以缓存需要的文件,那么在下次用户访问的时候就可以通过拦截请求的方式查询是否存在缓存,存在缓存的话就可以直接读取缓存文件,否则就去请求数据。
当 Service Worker 没有命中缓存的时候,我们需要去调用 fetch 函数获取数据。也就是说,如果我们没有在 Service Worker 命中缓存的话,会根据缓存查找优先级去查找数据。但是不管我们是从 Memory Cache 中还是从网络请求中获取的数据,浏览器都会显示我们是从 Service Worker中获取的内容。
在发起 http 请求之前,浏览器首先要做去获得我们想访问网页的 IP 地址,浏览器会发送一个 UDP 的包给 DNS 域名解析服务器。
递归查询
我们的浏览器、操作系统、路由器都会缓存一些 URL 对应的 IP 地址,统称为 DNS 高速缓存。这是为了加快 DNS 解析速度,使得不必每次都到根域名服务器中去查询。
迭代查询
迭代查询的方式就是,局部的 DNS 服务器并不会自己向其他服务器进行查询,而是把能够解析该域名的服务器 IP 地址返回给客户端,客户端会不断的向这些服务器进行查询,直到查询到了位置,迭代的话只会帮你找到相关的服务器,然后说我现在比较忙,你自己去找吧。
DNS 负载均衡
DNS 还有负载均衡的作用,现在很多网站都有多个服务器,当一个网站访问量过大的时候,如果所有请求都请求在同一个服务器上,可能服务器就会崩掉,这时候就用到了 DNS 负载均衡技术,当一个网站有多个服务器地址时,在应答 DNS 查询的时候,DNS 服务器会对每个查询返回不同的解析结果,也就是返回不同的 IP 地址,从而把访问引导到不同的服务器上去,来达到负载均衡的目的。例如可以根据每台机器的负载量,或者该机器距离用户的地理位置距离等等条件。
DNS 预解析
大型网站,有多个不同服务器资源的情况下,都可采取 DNS 预解析,提前解析,减少页面卡顿。
第二部分 TCP/IP 连接:三次握手
网络协议分层
TCP/IP 协议
TCP(Transmission Control Protocol) 传输控制协议。 TCP/IP 协议将应用层、表示层、会话层合并为应用层,物理层和数据链路层合并为网络接口层。
TCP/IP 协议不仅仅指的是 TCP 和 IP 两个协议,⽽是指的⼀个由 FTP,SMTP,TCP,UDP,IP,ARP 等等协议构成的协议集合。
第一次握手:主机 A 发送位码为SYN=1,随机产生Seq number=1234567的数据包到服务器,主机 B 由SYN=1知道,A 要求建立联机;(第一次握手,由浏览器发起,告诉服务器我要发送请求了)
第二次握手:主机 B 收到请求后要确认联机信息,向 A 发送ack number=(主机 A 的 seq+1),SUN=1,ACK=1234567 + 1,随机产生Seq=7654321的包;(第二次握手,由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧)
第三次握手:主机 A 收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码SYN是否为 1,若正确,主机 A 会再发送ack number=(主机 B 的 seq+1),ack=7654321 + 1,主机 B 收到后确认Seq值与ACK=7654321+ 1则连接建立成功;(第三次握手,由浏览器发送,告诉服务器,我马上就发了,准备接受吧)
为什么这样呢? 大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。
也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。
SYN 攻击?
服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到 SYN 洪泛攻击。SYN 攻击就是 Client 在短时间内伪造大量不存在的 IP 地址,并向 Server 不断地发送 SYN 包,Server 则回复确认包,并等待 Client 确认,由于源地址不存在,因此 Server 需要不断重发直至超时,这些伪造的 SYN 包将长时间占用未连接队列,导致正常的 SYN 请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。
检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源 IP 地址是随机的,基本上可以断定这是一次 SYN 攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。
netstat -n -p TCP | grep SYN_RECV
复制代码
常见的防御 SYN 攻击的方法有如下几种:
缩短超时(SYN Timeout)时间
增加最大半连接数
过滤网关防护
SYN cookies 技术
第三部分 HTTP 请求
HTTP 发展历史
HTTP/0.9
只有一个命令 GET
响应类型: 仅 超文本
没有 header 等描述数据的信息
服务器发送完毕,就关闭 TCP 连接
HTTP/1.0
增加了很多命令(post HESD )
增加status code 和 header
多字符集支持、多部分发送、权限、缓存等
响应:不再只限于超文本 (Content-Type 头部提供了传输 HTML 之外文件的能力 — 如脚本、样式或媒体文件)
因为当服务端收到客户端的 SYN 连接请求报文后,可以直接发送 SYN+ACK 报文。其中 ACK 报文是用来应答的,SYN 报文是用来同步的。但是关闭连接时,当服务端收到 FIN 报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个 ACK 报文,告诉客户端,“你发的 FIN 报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送 FIN 报文,因此不能一起发送。故需要四次挥手。
前置内容 浏览器主要进程
浏览器是多进程的,主要分为:
第一部分 输入网址并解析
这里我们只考虑输入的是一个 URL 结构字符串,如果是非 URL 结构的字符串,则会用浏览器默认的搜索引擎搜索该字符串。
URL 的组成
URL 主要由
协议
、主机
、端口
、路径
、查询参数
、锚点
6 部分组成!解析 URL
输入 URL 后,浏览器会解析出协议、主机、端口、路径等信息,并构造一个 HTTP 请求。
expires
和cache-control
判断是否命中(包括是否过期)强缓存策略,如果命中,直接从缓存获取资源,并不会发送请求。如果没有命中,则进入下一步。If-Modified-Since
和If-None-Match
判断是否命中协商缓存,如果命中,直接从缓存获取资源。如果没有命中,则进入下一步。HSTS
由于安全隐患,会使用 HSTS 强制客户端使用 HTTPS 访问页面。详见:你所不知道的 HSTS。 当你的网站均采用 HTTPS,并符合它的安全规范,就可以申请加入 HSTS 列表,之后用户不加 HTTPS 协议再去访问你的网站,浏览器都会定向到 HTTPS。无论匹配到没有,都要开始 DNS 查询工作了。
浏览器缓存
强缓存
强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程。强缓存又分为两种
Expires
和Cache-Control
Expires
Cache-Control
请求头:
响应头:
示例:
协商缓存
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。
模拟 Last-Modified
模拟 ETag
Last-Modified(响应头),If-Modified-Since(请求头)
在浏览器第一次给服务器发送请求后,服务器会在响应头中加上这个字段。 浏览器接收到后,如果再次请求,会在请求头中携带
If-Modified-Since
字段,这个字段的值也就是服务器传来的最后修改时间。 服务器拿到请求头中的If-Modified-Since
的字段后,其实会和这个服务器中该资源的最后修改时间Last-Modified
对比, 询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来。但是如果在本地打开缓存文件,就会造成
Last-Modified
被修改,所以在HTTP / 1.1
出现了ETag
。ETag(响应头)、If-None-Match(请求头)
ETag
是服务器根据当前文件的内容,给文件生成的唯一标识,只要里面的内容有改动,这个值就会变。服务器通过响应头把这个值给浏览器。 浏览器接收到 ETag 的值,会在下次请求时,将这个值作为If-None-Match
这个字段的内容,并放到请求头中,然后发给服务器。存储位置
Service Worker
是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。使用Service Worker
的话,传输协议必须为HTTPS
。因为Service Worker
中涉及到请求拦截,所以必须使用HTTPS
协议来保障安全。Service Worker
的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。Service Worker
实现缓存功能一般分为三个步骤:首先需要先注册Service Worker
,然后监听到install
事件以后就可以缓存需要的文件,那么在下次用户访问的时候就可以通过拦截请求的方式查询是否存在缓存,存在缓存的话就可以直接读取缓存文件,否则就去请求数据。当
Service Worker
没有命中缓存的时候,我们需要去调用fetch
函数获取数据。也就是说,如果我们没有在Service Worker
命中缓存的话,会根据缓存查找优先级去查找数据。但是不管我们是从Memory Cache
中还是从网络请求中获取的数据,浏览器都会显示我们是从Service Worker
中获取的内容。Memory Cache
也就是内存中的缓存,主要包含的是当前中页面中已经抓取到的资源, 例如页面上已经下载的样式、脚本、图片等。读取内存中的数据肯定比磁盘快, 内存缓存虽然读取高效,可是缓存持续性很短,会随着进程的释放而释放。 一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。那么既然内存缓存这么高效,我们是不是能让数据都存放在内存中呢? 这是不可能的。计算机中的内存一定比硬盘容量小得多,操作系统需要精打细算内存的使用,所以能让我们使用的内存必然不多。
Disk Cache
也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之Memory Cache
胜在容量和存储时效性上。Push Cache
(推送缓存)是HTTP/2
中的内容,当以上三种缓存都没有命中时,它才会被使用。它只在会话(Session)中存在,一旦会话结束就被释放,并且缓存时间也很短暂,在 Chrome 浏览器中只有 5 分钟左右,同时它也并非严格执行 HTTP 头中的缓存指令。Edge
和Safari
浏览器支持相对比较差no-cache
和no-store
的资源Push Cache
就被释放HTTP/2
的连接,也就可以使用同一个Push Cache
。这主要还是依赖浏览器的实现而定,出于对性能的考虑,有的浏览器会对相同域名但不同的 tab 标签使用同一个 HTTP 连接。Push Cache
中的缓存只能被使用一次DNS 域名解析
在发起 http 请求之前,浏览器首先要做去获得我们想访问网页的 IP 地址,浏览器会发送一个 UDP 的包给 DNS 域名解析服务器。
递归查询
我们的浏览器、操作系统、路由器都会缓存一些 URL 对应的 IP 地址,统称为 DNS 高速缓存。这是为了加快 DNS 解析速度,使得不必每次都到根域名服务器中去查询。
迭代查询
迭代查询的方式就是,局部的 DNS 服务器并不会自己向其他服务器进行查询,而是把能够解析该域名的服务器 IP 地址返回给客户端,客户端会不断的向这些服务器进行查询,直到查询到了位置,迭代的话只会帮你找到相关的服务器,然后说我现在比较忙,你自己去找吧。
DNS 负载均衡
DNS 还有负载均衡的作用,现在很多网站都有多个服务器,当一个网站访问量过大的时候,如果所有请求都请求在同一个服务器上,可能服务器就会崩掉,这时候就用到了 DNS 负载均衡技术,当一个网站有多个服务器地址时,在应答 DNS 查询的时候,DNS 服务器会对每个查询返回不同的解析结果,也就是返回不同的 IP 地址,从而把访问引导到不同的服务器上去,来达到负载均衡的目的。例如可以根据每台机器的负载量,或者该机器距离用户的地理位置距离等等条件。
DNS 预解析
大型网站,有多个不同服务器资源的情况下,都可采取 DNS 预解析,提前解析,减少页面卡顿。
第二部分 TCP/IP 连接:三次握手
网络协议分层
TCP/IP 协议
TCP(Transmission Control Protocol) 传输控制协议。 TCP/IP 协议将应用层、表示层、会话层合并为应用层,物理层和数据链路层合并为网络接口层。
三次握手
客服端和服务端在进行 http 请求和返回的工程中,需要创建一个
TCP connection
(由客户端发起),http
不存在连接这个概念,它只有请求和响应。请求和响应都是数据包,它们之间的传输通道就是TCP connection
。位码即 tcp 标志位,有 6 种标示:
第一次握手:主机 A 发送位码为
SYN=1
,随机产生Seq number=1234567
的数据包到服务器,主机 B 由SYN=1
知道,A 要求建立联机;(第一次握手,由浏览器发起,告诉服务器我要发送请求了)第二次握手:主机 B 收到请求后要确认联机信息,向 A 发送
ack number=(主机 A 的 seq+1)
,SUN=1,ACK=1234567 + 1
,随机产生Seq=7654321
的包;(第二次握手,由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧)第三次握手:主机 A 收到后检查
ack number
是否正确,即第一次发送的seq number+1
,以及位码SYN
是否为 1,若正确,主机 A 会再发送ack number=(主机 B 的 seq+1)
,ack=7654321 + 1
,主机 B 收到后确认Seq
值与ACK=7654321+ 1
则连接建立成功;(第三次握手,由浏览器发送,告诉服务器,我马上就发了,准备接受吧)第三次握手的必要性?
试想如果是用两次握手,则会出现下面这种情况: 如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源。
什么是半连接队列?
服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列。
当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。
这里在补充一点关于 SYN-ACK 重传次数的问题: 服务器发送完 SYN-ACK 包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。
注意,每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间为 1s,2s,4s,8s…
ISN 是固定的吗?
当一端为建立连接而发送它的 SYN 时,它为连接选择一个初始序号。ISN 随时间而变化,因此每个连接都将具有不同的 ISN。ISN 可以看作是一个 32 比特的计数器,每 4ms 加 1 。这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送,而导致某个连接的一方对它做错误的解释。
三次握手的其中一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number),以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的,攻击者很容易猜出后续的确认号,因此 ISN 是动态生成的。
三次握手过程中可以携带数据吗?
其实第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手不可以携带数据。
为什么这样呢? 大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。
也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。
SYN 攻击?
服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到 SYN 洪泛攻击。SYN 攻击就是 Client 在短时间内伪造大量不存在的 IP 地址,并向 Server 不断地发送 SYN 包,Server 则回复确认包,并等待 Client 确认,由于源地址不存在,因此 Server 需要不断重发直至超时,这些伪造的 SYN 包将长时间占用未连接队列,导致正常的 SYN 请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。
检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源 IP 地址是随机的,基本上可以断定这是一次 SYN 攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。
常见的防御 SYN 攻击的方法有如下几种:
第三部分 HTTP 请求
HTTP 发展历史
HTTP/0.9
HTTP/1.0
status code
和header
HTTP/1.1
GET
,HEAD
,POST
,PUT
,DELETE
,TRACE
,OPTIONS
HTTP2
HTTP3
HTTP3 的主要改进在传输层上。传输层不会再有我前面提到的那些繁重的 TCP 连接了。现在,一切都会走 UDP。
HTTP3 详细介绍
HTTP 协议特点
HTTP 报文
请求报文:
响应报文:
各协议与 HTTP 协议关系
HTTPS
在 HTTP 的基础上再加一层 TLS(传输层安全性协议)或者 SSL(安全套接层),就构成了 HTTPS 协议。
HTTPS 默认工作在 TCP 协议 443 端口,它的工作流程一般如以下方式:
Client Hello
消息,其中携带客户端支持的协议版本、加密算法、压缩算法以及客户端生成的随机数;Server Hello
消息,并携带选择特定的协议版本、加密方法、会话 ID 以及服务端生成的随机数;Certificate
消息,即服务端的证书链,其中包含证书支持的域名、发行方和有效期等信息;Server Key Exchange
消息,传递公钥以及签名等信息;Certificate Request
,验证客户端的证书;Server Hello Done
消息,通知服务端已经发送了全部的相关信息;Client Key Exchange
消息,包含使用服务端公钥加密后的随机字符串,即预主密钥(Pre Master Secret
);Change Cipher Spec
消息,通知服务端后面的数据段会加密传输;Finished
消息,其中包含加密后的握手信息;Change Cipher Spec
和Finished
消息后;Change Cipher Spec
消息,通知客户端后面的数据段会加密传输;Finished
消息,验证客户端的Finished
消息并完成 TLS 握手;TLS 握手的关键在于利用通信双发生成的随机字符串和服务端的证书公钥生成一个双方经过协商后的对称密钥,这样通信双方就可以使用这个对称密钥在后续的数据传输中加密消息数据,防止中间人的监听和攻击,保证通讯安全。
第四部分 服务器处理请求并返回 HTTP 报文
每台服务器上都会安装处理请求的应用——Web Server。常见的 Web Server 产品有
apache
、nginx
、IIS
或Lighttpd
等。HTTP 请求一般可以分为两类,静态资源 和 动态资源。
请求访问静态资源,这个就直接根据 url 地址去服务器里找就好了。
请求动态资源的话,就需要 web server 把不同请求,委托给服务器上处理相应请求的程序进行处理(例如 CGI 脚本,JSP 脚本,servlets,ASP 脚本,服务器端 JavaScript,或者一些其它的服务器端技术等),然后返回后台程序处理产生的结果作为响应,发送到客户端。
服务器在处理请求的时候主要有三种方式:
第五部分 浏览器渲染页面
DOM 树
字节 → 字符 → 令牌 → 节点 → 对象模型。
CSS 对象模型 (CSSOM)
布局树 Layout Tree
渲染
渲染流程:
创建图层
在 chrome 上查看 Layers.
如果没有打开 Layers, 按下图打开:
回流和重绘
当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility 等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
当 Render Tree 中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。
引起回流:
引起回流的属性和方法:
如何减少回流
第六部分 断开连接:TCP 四次分手
挥手为什么需要四次?
因为当服务端收到客户端的 SYN 连接请求报文后,可以直接发送 SYN+ACK 报文。其中 ACK 报文是用来应答的,SYN 报文是用来同步的。但是关闭连接时,当服务端收到 FIN 报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个 ACK 报文,告诉客户端,“你发的 FIN 报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送 FIN 报文,因此不能一起发送。故需要四次挥手。
为什么客户端发送 ACK 之后不直接关闭,而是要等一阵子才关闭?
客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入 TIME_WAIT(时间等待)状态。此时 TCP 未释放掉,需要经过时间等待计时器设置的时间 2MSL 后,客户端才进入 CLOSED 状态。如果不等待,客户端直接跑路,当服务端还有很多数据包要给客户端发,且还在路上的时候,若客户端的端口此时刚好被新的应用占用,那么就接收到了无用数据包,造成数据包混乱。
为什么 TIME_WAIT 状态需要经过 2MSL(最大报文生存时间)才能返回到 CLOSE 状态?
理论上,四个报文都发送完毕,就可以直接进入 CLOSE 状态了,但是可能网络是不可靠的,有可能最后一个 ACK 丢失。所以 TIME_WAIT 状态就是用来重发可能丢失的 ACK 报文。 1 个 MSL 确保四次挥手中主动关闭方最后的 ACK 报文最终能达到对端; 1 个 MSL 确保对端没有收到 ACK 重传的 FIN 报文可以到达。
关于 HTTP
如果想要高清大图或者 Xmind 文件的话,可以私信 lian x
站在巨人的肩膀上
在这里对前辈大佬表示敬意,查找了很多资料,如有遗漏,还请见谅。文中如果有误,还望及时指出,感谢!
5 分钟看懂 HTTP3 一文带你了解 HTTPS 从 URL 输入到页面展现到底发生什么? 从 URL 输入到页面展现到底发生什么? 在浏览器上请求一个 URL 的全部过程 前端经典面试题: 从输入 URL 到页面加载发生了什么? 浏览器缓存看这一篇就够了 从输入 URL 到浏览器显示页面的流程 在浏览器输入 URL 回车之后发生了什么(超详细版) TCP 和 Http 的区别! 我都搞懂了, 你就别迷糊了! 为什么 HTTPS 需要 7 次握手以及 9 倍时延 渲染树构建、布局及绘制 浏览器渲染详细过程:重绘、重排和 composite 只是冰山一角 浏览器渲染机制和 Reflow(回流、重排)和 Repaint(重绘) 问我 Chrome 浏览器的渲染原理(6000 字长文) 浅谈浏览器的图层与重绘重排(详细),以及如何用于性能优化 HTTP 笔记 1:Web 基础及简单的 HTTP 协议 图解 HTTP-21 张图把 HTTP 安排得明明白白 HTTP3 一文带你了解 HTTPS 浏览器工作原理与实践
https://juejin.cn/post/6935232082482298911
The text was updated successfully, but these errors were encountered: