浏览器相关知识点

Web 应用趋势

  • 应用程序 Web 化,视频 , 音频 ,游戏的占比越来越高

  • 是 Web 应用移动化, Google 推出了 PWA 方案来整合 Web 和本地程序各自的优势

  • Web 操作系统化 ,可能以后浏览器会提供更多的模块给上层应用使用,如新支持的 WebAssembly;

OSI 七层网络模型

  • 应用层: HTTP,HTTPS,FTP,NFS,FMTP,DHCP,SNMP,TELNET,POP3,IRC,NNTP 这些应用层协议为应用提供服务,可以执行用户活动。
  • 表示层: 从应用层接受数据,并将 ASCII 码转化为 EBCDIC 码(二进制),执行数据压缩(有损/无损),使用 SSL (加密/解密)保证数据安全。
  • 会话层: 会话管理,身份验证,授权方面
  • 传输层:TCP,UDP, 流量控制,数据校验
  • 网络层:IP 逻辑寻址
  • 数据链层: 数据单元被称之为帧
  • 物理层:传输物理信号

进程与线程

进程是一个程序的运行实例,启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,我们把这样的一个运行环境叫进程。 线程是依附于进程的,而进程中使用多线程并行处理能提升运算效率。

进程和线程之间的关系有以下特点:

  • 进程中的任意一线程执行出错,都会导致整个进程的崩溃。

  • 线程之间可以对进程的公共数据进行读写操作。

  • 当一个进程关闭之后,操作系统会回收进程所占用的内存。

    虽然有些程序因为代码原因,或安装了额外的插件,可能导致内存泄漏.但只要关闭进程,内存就会被回收.

  • 进程之间的内容相互隔离。

    进程隔离是为保护操作系统中进程互不干扰的技术,每一个进程只能访问自己占有的数据.所以一个进程如果崩溃了,或者挂起了,是不会影响到其他进程的。如果进程之间需要进行数据的通信,这时候,就需要使用用于进程间通信(IPC)的机制了。

目前浏览器主要包含以下几个进程, 查看 Chrome 的进程类型

  • 1 个浏览器进程。主要负责界面显示、用户交互、子进程管理,同时提供存储等功能

  • 多个渲染进程。核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。

  • 1 个 GPU 进程。其实,Chrome 刚开始发布的时候是没有 GPU 进程的。而 GPU 的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器普遍的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程。

  • 1 个网络进程。主要负责页面的网络资源加载,之前是作为一个模块运行在浏览器进程里面的,后面独立出来,成为一个单独的进程。

  • 多个插件进程。主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。

渲染进程的个数如何计算:

  • 如果从一个标签页中打开了另一个新标签页,当新标签页和当前标签页属于同一站点的话,那么新标签页会复用当前标签页的渲染进程。 Chrome 浏览器会将浏览上下文组中属于同一站点的标签分配到同一个渲染进程中,要同时满足 A 和 B 属于同一站点,且 A 和 B 之间有链接关系
    <a> 元素的 rel 属性为 noopener noreferrer 时会阻止使用同一个渲染进程。
  • chrome 浏览器实现了站点隔离,所以 iframe 也会遵循以下的渲染规则,如果和父页面属于同一站点,且有链接关系,也会运行在相同的渲染进程中。

请求的各个阶段

DNS 域名解析过程

域名使用 . 划分, 最后由根域名服务器统一管理,根域名服务器是一个服务器集群,有十几个根域名,但是有一千多台根域名服务器,这就需要通过任播技术找到最近的一台根域名服务器。

顶级域名服务器会管理 .net .com 这些域名, 权威域名服务器会管理 .qq baidu 这些域名。

  • 发起解析前会检查本地是否有缓存文件。

  • 调用 DNS 客户端发起查询请求,本地的 DNS 服务端一般有互联网服务提供商(ISP)管理,DNS 服务端会查询是否有缓存,如果有则返回带有 Non-authoritative 字段的数据。如果是根域名服务器则返回带有 Authoritative 的字段。缓存需要定期更新。
    DNS 迭代查询的时候使用的时 UDP 请求,数据量比较小,可以用一个 UDP 包返回,比较注重效率。更新缓存时使用的时 TCP 查询。

  • 获取最近的根域名服务器的地址,查询 .com 域名的服务器地址。

  • 获取最近的 .com 服务器的地址,查询 baidu.com 的服务器地址。

  • 获取最近的 baidu.com 权威域名服务器的地址,查询 mail.baidu.com 对应的 IP。

  • 可能会返回 mail.baidu.com 对应的 CDN(内容分发服务器) 地址,这就是最终的地址。

DNS 预解析

dns-prefetch(DNS 预获取)是前端网络性能优化的一种措施。它根据浏览器定义的规则,提前解析之后可能会用到的域名,使解析结果缓存到系统缓存中,缩短 DNS 解析时间,进而提高网站的访问速度。

每当在首次 DNS 解析后会对其 IP 进行缓存。至于缓存时长,每种浏览器都不一样,比如 Chrome 的过期时间是 1 分钟,在这个期限内不会重新请求 DNS。

每当 Chrome 浏览器启动的时候,就会自动的快速解析浏览器最近一次启动时记录的前 10 个域名。所以经常访问的网址就不存在 DNS 解析的延迟,进而打开速度更快。

  • dns-prefetch 仅对跨域域上的 DNS 查找有效,因此请避免使用它来指向相同域。这是因为,到浏览器看到提示时,您站点域背后的 IP 已经被解析。

  • http 页面下所有的 a 标签的 href 都会自动去启用 DNS Prefetch,也就是说网页的 a 标签 href 带的域名,是不需要在 head 里面加上 link 手动设置的。

    可以通过在服务器端发送 X-DNS-Prefetch-Control 报头,或是在文档中使用值为 http-equiv 的 <meta> 标签:

    1
    <meta http-equiv="x-dns-prefetch-control" content="on" />
  • 强制查询特定主机名,使用 rel 属性值为 link type 中的 dns-prefetch 的 标签来对特定域名进行预读取:

    1
    <link rel="dns-prefetch" href="http://www.baidu.com/" />
Keep-Alive

通常情况下,一旦服务器向客户端返回了请求数据,它就要关闭 TCP 连接。不过如果浏览器或者服务器在其头信息中加入了:

1
Connection:Keep-Alive

那么 TCP 连接在发送后将仍然保持打开状态,这样浏览器就可以继续通过同一个 TCP 连接发送请求。保持 TCP 连接可以省去下次请求时需要建立连接的时间,提升资源加载速度。比如,一个 Web 页面中内嵌的图片就都来自同一个 Web 站点,如果初始化了一个持久连接,你就可以复用该连接,以请求其他资源,而不需要重新再建立新的 TCP 连接。

如何保证页面文件能被完整地送达浏览器?

在网络中,一个文件通常会被拆分为很多数据包来进行传输,而数据包在传输过程中又有很大概率丢失或者出错。

联网,实际上是一套理念和协议组成的体系架构。其中,协议是一套众所周知的规则和标准,如果各方都同意使用,那么它们之间的通信将变得毫无障碍。

IP:把数据包送达目的主机

数据包要在互联网上进行传输,就要符合网际协议(Internet Protocol,简称 IP)标准, 访问网站就是向另一台有明确地址的计算机请求信息.

想通信一定要知道双方 IP 地址, 这些附加的信息会被装进一个叫 IP 头的数据结构里。IP 头是 IP 数据包开头的信息,包含 IP 版本、源 IP 地址、目标 IP 地址、生存时间等信息

  • 将要发送的数据交给网络进程
  • 创建 IP 头并附加到数据包上,并交给底层传输
  • 底层通过物理网络,将数据发送到 B
  • 数据被传输到 B 的网络层,会拆开 IP 头信息,并将数据交给上层处理
UDP:把数据包送达应用程序

到达主机后还需要把数据送给应用,,需要基于 IP 之上开发能和应用打交道的协议,最常见的是 用户数据包协议(User Datagram Protocol),简称 UDP。

UDP 中一个最重要的信息是端口号,端口号其实就是一个数字,每个想访问网络的程序都需要绑定一个端口号。通过端口号 UDP 就能把指定的数据包发送给指定的程序了,所以 IP 通过 IP 地址信息把数据包发送给指定的电脑,而 UDP 通过端口号把数据包分发给正确的程序。和 IP 头一样,端口号会被装进 UDP 头里面,UDP 头再和原始数据包合并组成新的 UDP 数据包。UDP 头中除了目的端口,还有源端口号等信息。

虽然 UDP 可以校验数据是否正确,但是对于错误的数据包,UDP 并不提供重发机制,只是丢弃当前的包,而且 UDP 在发送之后也无法知道是否能达到目的地。虽说 UDP 不能保证数据可靠性,但是传输速度却非常快,所以 UDP 会应用在一些关注速度、但不那么严格要求数据完整性的领域,如在线视频、互动游戏等。

  • 传输层会在数据包前面附加上 UDP 头,组成新的 UDP 数据包,再将新的 UDP 数据包交给网络层
  • 网络层再将 IP 头附加到数据包上,组成新的 IP 数据包,并交给底层;
  • 数据包被传输到主机 B 的网络层,在这里主机 B 拆开 IP 头信息,并将拆开来的数据部分交给传输层;
  • 在传输层,数据包中的 UDP 头会被拆开,并根据 UDP 中所提供的端口号,把数据部分交给上层的应用程序;
TCP:确保数据包的完整性

使用 UDP 来传输会存在两个问题:

  • 数据包在传输过程中容易丢失;

  • 大文件会被拆分成很多小的数据包来传输,这些小的数据包会经过不同的路由,并在不同的时间到达接收端,而 UDP 协议并不知道如何组装这些数据包,从而把这些数据包还原成完整的文件。

基于这两个问题,我们引入 TCP 了。TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。相对于 UDP,TCP 有下面两个特点:

  • 对于数据包丢失的情况,TCP 提供重传机制;

  • TCP 引入了数据包排序机制,用来保证把乱序的数据包组合成一个完整的文件。

既然要实现重传和数据包排序,必然需要一套链接机制,这也就是三次握手,和四次挥手

  • 首先,建立连接阶段。这个阶段是通过三次握手来建立客户端和服务器之间的连接。TCP 提供面向连接的通信传输。面向连接是指在数据通信开始之前先做好两端之间的准备工作,通过三次握手建立链接.

  • 其次,传输数据阶段。在该阶段,接收端需要对每个数据包进行确认操作,也就是接收端在接收到数据包之后,需要发送确认数据包给发送端。所以当发送端发送了一个数据包之后,在规定时间内没有接收到接收端反馈的确认消息,则判断为数据包丢失,并触发发送端的重发机制。同样,一个大的文件在传输过程中会被拆分成很多小的数据包,这些数据包到达接收端后,接收端会按照 TCP 头中的序号为其排序,从而保证组成完整的数据。

  • 最后,断开连接阶段。数据传输完毕之后,就要终止连接了,涉及到最后一个阶段“四次挥手”来保证双方都能断开连接。

流量控制:通过滑动窗口,取值为 min(拥塞窗口,接受窗口);
拥塞控制:慢启动(从 1 开始指数增加),达到阈值之后每次+1(拥塞避免),如果超时阈值修改为当前窗口的一半,重新慢启动开始传输。(TCP Tahoe 版本已废弃)
快重传,快恢复,如果接收到三个确认重传的 ack,会直接将阈值修改为当前窗口的一半,并每次传输时窗口大小增加 1(拥塞避免)。(TCP Reno 版本)

HTTP1.1 HTTP2 HTTP3

  • HTTP1.1

    增加了持久连接的方法,它的特点是在一个 TCP 连接上可以传输多个 HTTP 请求,只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持,持久连接在 HTTP/1.1 中是默认开启的,所以你不需要专门为了持久连接去 HTTP 请求头设置信息,如果你不想要采用持久连接,可以在 HTTP 请求头中加上 Connection: close。目前浏览器中对于同一个域名,默认允许同时建立 6 个 TCP 持久连接。

    提供虚拟主机的支持,HTTP/1.0 中,每个域名绑定了一个唯一的 IP 地址,因此一个服务器只能支持一个域名.但是随着虚拟主机技术的发展,需要实现在一台物理主机上绑定多个虚拟主机,每个虚拟主机都有自己的单独的域名,这些单独的域名都公用同一个 IP 地址。HTTP/1.1 的请求头中增加了 Host 字段,用来表示当前的域名地址,这样服务器就可以根据不同的 Host 值做不同的处理。

    对动态生成的内容提供了支持,在设计 HTTP/1.0 时,需要在响应头中设置完整的数据大小,但是大部分页面内容都是动态的,,因此在传输数据之前并不知道最终的数据大小。HTTP/1.1 通过引入 Chunk transfer 机制来解决这个问题,服务器会将数据分割成若干个任意大小的数据块,每个数据块发送时会附上上个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。这样就提供了对动态内容的支持。

    安全性,cookies

    存在的问题

    TCP 慢启动,导致小的核心资源并不能占满带宽立即下载
    多个 TCP 链接会竞争贷款,可能让核心资源的下载速度变慢
    队头阻塞的问题,同一时间只能一个 TCP 链接只能处理一个请求,其他的任务需要排队
    头信息没有压缩,并且被频繁的重复传输

  • HTTP2
    解决 HTTP1.1 存在的问题 一个域名只使用一个 TCP 长连接和消除队头阻塞问题 。但是 HTTP2 仍然是基于 TCP 协议的,TCP 传输过程中的丢包,会导致 TCP 队头阻塞,所以随着丢包率的增加,HTTP/2 的传输效率也会越来越差。有测试数据表明,当系统达到了 2% 的丢包率时,HTTP/1.1 的传输效率反而比 HTTP/2 表现得更好。

    HTTP2 构建了一个 2 进制分帧层,其中是两个核心概念。帧是数据传输的最小单位。帧的最外层格式如下。

    HTTP2 把请求和响应报文分成头部帧和数据帧。由 type 字段标识。一个流用多个帧组成,同一个流的帧共用一个流 ID 标识,可以将乱序的帧关联起来。

    使用 HPACK 算法,减少头信息的小,减小发送包的体积,从而降低延迟。此算法包含静态表,动态表,Huffman 编码,静态表预定义了 61 个 header 的 key,value。动态表由双方维护自定义的 header 字段,Huffman 编码用于消除重复的字节。

    可以设置请求的权重,高优先级的请求会优先响应。
    可以服务端推送,如果请求的网页有依赖资源,服务器会主动将资源推送到客户端。

    但是 HTTP2 并没有解决 TCP 层面的队头阻塞,如果传输过程中的包丢失,依然会重传并等待。

  • HTTP3
    在 UDP 协议之上,实现了 QUIC 协议,实现了类似 TCP 的流量控制、传输可靠性的功能。虽然 UDP 不提供可靠性的传输,但 QUIC 在 UDP 的基础之上增加了一层来保证数据可靠性传输。它提供了数据包重传、拥塞控制以及其他一些 TCP 中存在的特性。

    集成了 TLS 加密功能。目前 QUIC 使用的是 TLS1.3,相较于早期版本 TLS1.3 有更多的优点,其中最重要的一点是减少了握手所花费的 RTT 个数。

    实现了 HTTP/2 中的多路复用功能。和 TCP 不同,QUIC 实现了在同一物理连接上可以有多个独立的逻辑数据流(如下图)。实现了数据流的单独传输,就解决了 TCP 中队头阻塞的问题。

    实现了快速握手功能。由于 QUIC 是基于 UDP 的,所以 QUIC 可以实现使用 0-RTT 或者 1-RTT 来建立连接,这意味着 QUIC 可以用最快的速度来发送和接收数据,这样可以大大提升首次打开页面的速度。

    同时也存在一下问题:

    浏览器的实现和官方定义差距过大,系统内核对 UPD 的优化不佳。中间设备僵化导致丢包率远大于 TCP 链接。

TLS 握手过程

  • 客户端发送给服务端,TLS 版本,加密套件,seq(随机数)1
  • 服务端响应 TLS 版本,加密套件,seq2
  • 服务端发送证书
  • 服务端发送公钥
  • 服务点通知客户端发送完成
  • 客户端生成 seq3(预主密钥) 用接收到的公钥加密后在发送给服务端
  • 服务端用私钥解密,获取预主密钥
  • 服务端和客户端分别用 seq1+seq2+seq3(预主密钥) 生成会话密钥
  • 后续的通信使用会话密钥

TLS 只有在握手的过程中使用非对称加密,非对称加密对资源的消耗很大,通信过程使用加密后的会话密钥。

报文格式

  • HTTP

页面性能指标

  • FP(First Paint):从开始加载到浏览器首次绘制像素到屏幕上的时间,也就是页面在屏幕上首次发生视觉变化的时间。

  • FCP(First Contentful Paint):浏览器首次绘制来自 DOM 的内容的时间。这是用户第一次开始看到页面内容,但仅仅有内容,并不意味着它是有用的内容(例如 Header、导航栏等),也不意味着有用户要消费的内容。

  • FMP(First Meaningful Paint):页面的主要内容绘制到屏幕上的时间。主要内容的定义因页面而异,例如对于博客文章,它的主要内容是标题和摘要,对于搜索页面,它的主要内容是搜索结果,对于电商的页面,图片则是主要内容。

  • FSP(First Screen Paint):页面从开始加载到首屏内容全部绘制完成的时间,用户可以看到首屏的全部内容。

  • TTI(Time to Interactive):表示网页第一次完全达到可交互状态的时间点,浏览器已经可以持续性的响应用户的输入。

HTTP 缓存

强制缓存

HTTP/1.1 定义的 Cache-Control 头用来区分对缓存机制的支持情况, 请求头和响应头都支持这个属性。通过它提供的不同的值来定义缓存策略。

  • 每次都提供最新的内容

    此方式下,每次有请求发出时,缓存会将此请求发到服务器(该请求应该会带有与本地缓存相关的验证字段),服务器端会验证请求中所描述的缓存是否过期,若未过期(注:实际就是返回 304),则缓存才使用本地缓存副本。

    1
    Cache-Control: no-cache
  • 过期
    过期机制中,最重要的指令是 “max-age=“,表示资源能够被缓存(保持新鲜)的最大时间。max-age 是距离请求发起的时间的秒数。针对应用中那些不会改变的文件,通常可以手动设置一定的时长以保证缓存有效,例如图片、css、js 等静态资源。

    Expires 响应头包含日期/时间, 即在此时候之后,响应过期。如果在 Cache-Control 响应头设置了 “max-age” 或者 “s-max-age” 指令,那么 Expires 头会被忽略。

协商缓存

强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存

  • Last-Modified / If-Modified-Since

    Last-Modified 是由服务器发送给客户端的 HTTP 响应头标签,时间值是当前资源文件的修改时间

    If-Modified-Since 是由客户端发送给服务器的 HTTP 请求头标签,客户端再次发起该请求时,会携带上次请求返回的 Last-Modified 的时间值,对比 If-Modified-Since 的时间和该资源在服务器端最后被修改的时间,决定是否更新资源

  • Etag / If-None-Match

    Etag 是由服务器发送给客户端的 HTTP 响应头标签,是服务器端生成的资源文件的一个唯一标识

    If-None-Match 是由客户端发送给服务器的 HTTP 请求头标签,客户端再次发起该请求时,会携带上次请求返回的 Etag 值,对比服务器端的 Etag 值和 If-None-Match 的值,决定是否更新资源

优先级:Etag / If-None-Match > Last-Modified / If-Modified-Since

重绘与重排

如果你通过 JavaScript 或者 CSS 修改元素的几何位置属性,例如改变元素的宽度、高度等,那么浏览器会触发重新布局,解析之后的一系列子阶段,这个过程就叫重排。无疑,重排需要更新完整的渲染流水线,所以开销也是最大的。

如果修改了元素的背景颜色,那么布局阶段将不会被执行,因为并没有引起几何位置的变换,所以就直接进入了绘制阶段,然后执行之后的一系列子阶段,这个过程就叫重绘。相较于重排操作,重绘省去了布局和分层阶段,所以执行效率会比重排操作要高一些。

如果更改一个既不要布局也不要绘制的属性,把这个过程叫做合成

使用了 CSS 的 transform 来实现动画效果,这可以避开重排和重绘阶段,直接在非主线程上执行合成动画操作。这样的效率是最高的,因为是在非主线程上合成,并没有占用主线程的资源,另外也避开了布局和绘制两个子阶段,所以相对于重绘和重排,合成能大大提升绘制效率。

请求时间线

  • Queuing(排队), 导致排队状态有很多
    遇到 CSS、HTML、JavaScript 等高优先级资源,图片、视频、音频 这些低优先级资源会让路。
    浏览器会为每个域名最多维护 6 个 TCP 连接,如果超过这个数量会处于排队状态。
    网络进程在为数据分配磁盘空间时,新的 HTTP 请求也需要短暂地等待磁盘分配结束。

    优化方案: 使用域名分片技术,提高整体的 TCP 链接数量, 把站点升级到 HTTP2。

  • Stalled(停滞), 一些其他的原因导致链接被推

  • Initial connection(初始化链接), 建立 TCP 所花费的时间如果是 HTTPS 请求,还会有 SSL 握手时间。

  • Request sent(请求发送),由于只需要把缓冲区中的数据发送出去,所以速度比较快。

  • TTFB(第一字节时间),收服务器第一个字节的数据,TTFB 时间越短,就说明服务器响应越快。

    优化方案: 提高运营商的网络带宽,使用 CDN 技术。服务器响应时间过长,问题可能出现在渲染,信息处理等方面,可以考虑提高缓存的使用效率。

  • Content Download(资源下载时间)

    优化方案: 压缩文件,流式传输。

如何验证数字证书

  • 申请数字证书
    网站需要准备一套私钥和公钥,私钥留着自己使用;
    向 CA 机构提交公钥、公司、站点等信息并等待认证,这个认证过程可能是收费的;
    CA 通过线上、线下等多种渠道来验证极客时间所提供信息的真实性,如公司是否存在、企业是否合法、域名是否归属该企业等;
    如信息审核通过,CA 会向极客时间签发认证的数字证书,包含了极客时间的公钥、组织信息、CA 的信息、有效时间、证书序列号等,这些信息都是明文的,同时包含一个 CA 生成的签名。

  • 浏览器验证证书合法性
    首先,浏览器利用证书的原始信息计算出信息摘要;然后,利用 CA 的公钥来解密数字证书中的数字签名,解密出来的数据也是信息摘要;最后,判断这两个信息摘要是否相等就可以了。
    浏览器是怎么获取到 CA 公钥的,当部署 HTTP 服务器的时候,除了部署当前的数字证书之外,还需要部署 CA 机构的数字证书,CA 机构的数字证书包括了 CA 的公钥,以及 CA 机构的一些基础信息。服务器会有两个数字证书,域名的数字证书,CA 机构的数字证书。然后在建立 HTTPS 链接时,服务器会将这两个证书一同发送给浏览器,于是浏览器就可以获取到 CA 的公钥了。
    证明 CA 机构的合法性,操作系统中内置这些 CA 机构的数字证书,,CA 机构众多,因此操作系统不可能将每家 CA 的数字证书都内置进操作系统。于是人们又想出来一个折中的方案,将颁发证书的机构划分为两种类型,根 CA(Root CAs)和中间 CA(Intermediates CAs),通常申请者都是向中间 CA 去申请证书的,而根 CA 作用就是给中间 CA 做认证,一个根 CA 会认证很多中间的 CA,而这些中间 CA 又可以去认证其他的中间 CA,也就形成了数字证书链

FAQ

  • 浏览器可以同时打开多个页签,他们端口一样吗?如果一样,数据怎么知道去哪个页签?

    端口一样的,网络进程知道每个 tcp 链接所对应的标签是那个,所以接收到数据后,会把数据分发给对应的渲染进程。

  • TCP 传送数据时 浏览器端就做渲染处理了么?如果前面数据包丢了 后面数据包先来是要等么?类似的那种实时渲染怎么处理?针对数据包的顺序性?

    接收到 http 响应头中的 content-type 类型时就开始准备渲染进程了,响应体数据一旦接受到便开始做 DOM 解析了!基于 http 不用担心数据包丢失的问题,因为丢包和重传都是在 tcp 层解决的。http 能保证数据按照顺序接收的(也就是说,从 tcp 到 http 的数据就已经是完整的了,即便是实时渲染,如果发生丢包也得在重传后才能开始渲染)

  • http 和 websocket 都是属于应用层的协议吗?

    都是应用层协议,而且 websocket 名字取的比较有迷惑性,其实和 socket 完全不一样,可以把 websocket 看出是 http 的改造版本,增加了服务器向客户端主动发送消息的能力。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2015-2025 SunZhiqi

此时无声胜有声!

支付宝
微信