从输入 URL 到页面加载完成的过程中都发生了什么事情?

原文:从输入 URL 到页面加载完成的过程中都发生了什么事情?

附带:一篇非常古老的浏览器原理剖析

这个大佬讲的太详细了(从键盘和触摸屏开始),我就捡了一些自己能看懂得来写

1. 从输入框到敲回车

操作系统 GUI 将输入事件传递到了浏览器中,在这过程中,浏览器可能会做一些预处理,比如 Chrome 会根据历史统计来预估所输入字符对应的网站,比如输入了「ba」,根据之前的历史发现 90% 的概率会访问「www.baidu.com 」,因此就会在输入回车前就马上开始建立 TCP 链接甚至渲染了,这里面还有很多其它策略。

接着是输入 URL 后的「回车」,这时浏览器会对 URL 进行检查,首先判断协议,如果是 http 就按照 Web 来处理,另外还会对这个 URL 进行安全检查,然后直接调用浏览器内核中的对应方法,比如 WebView 中的 loadUrl 方法。

在浏览器内核中会先查看缓存,然后设置 UA 等 HTTP 信息,接着调用不同平台下网络请求的方法。

2. HTTP 请求的发送

因为网络的底层实现是和内核相关的,所以这一部分需要针对不同平台进行处理,从应用层角度看主要做两件事情:通过 DNS 查询 IP、通过 Socket 发送数据。

2.1 DNS 查询

首先由本机所设置的 DNS 服务器(8.8.8.8)向 DNS 根节点查询负责 .com 区域的域务器,然后通过其中一个负责 .com 的服务器查询负责 baidu.com 的服务器,最后由其中一个 baidu.com 的域名服务器查询 fex.baidu.com 域名的地址。

2.2 通过 Socket 发送数据

有了 IP 地址,就可以通过 Socket API 来发送数据了,这时可以选择 TCP 或 UDP 协议

HTTP 常用的是 TCP 协议,由于 TCP 协议的具体细节到处都能看到,这里谈一下 TCP 的 Head-of-line blocking 问题:假设客户端的发送了 3 个 TCP 片段(segments),编号分别是 1、2、3,如果编号为 1 的包传输时丢了,即便编号 2 和 3 已经到达也只能等待,因为 TCP 协议需要保证顺序,这个问题在 HTTP pipelining 下更严重,因为 HTTP pipelining 可以让多个 HTTP 请求通过一个 TCP 发送,比如发送两张图片,可能第二张图片的数据已经全收到了,但还得等第一张图片的数据传到。

为了解决 TCP 协议的性能问题,Chrome 团队提出了 QUIC 协议,它是基于 UDP 实现的可靠传输,比起 TCP,它能减少很多来回(round trip)时间,还有前向纠错码(Forward Error Correction)等功能。目前 Google Plus、 Gmail、Google Search、blogspot、Youtube 等几乎大部分 Google 产品都在使用 QUIC。

浏览器对同一个域名有连接数限制,大部分是 6,我以前认为将这个连接数改大后会提升性能,但实际上并不是这样的,Chrome 团队有做过实验,发现从 6 改成 10 后性能反而下降了,造成这个现象的因素有很多,如建立连接的开销、拥塞控制等问题,而像 SPDY、HTTP 2.0 协议尽管只使用一个 TCP 连接来传输数据,但性能反而更好,而且还能实现请求优先级。

另外,因为 HTTP 请求是纯文本格式的,所以在 TCP 的数据段中可以直接分析 HTTP 的文本。

3. 服务器接收到数据后会进行哪些处理?

3.1 负载均衡

请求在进入到真正的应用服务器前,可能还会先经过负责负载均衡的机器,它的作用是将请求合理地分配到多个服务器上,同时具备具备防攻击等功能。

负载均衡具体实现有很多种,有直接基于硬件的 F5,有操作系统传输层(TCP)上的 LVS,也有在应用层(HTTP)实现的反向代理(也叫七层代理),接下来将介绍 LVS 及反向代理。
LVS 的作用是从对外看来只有一个 IP,而实际上这个 IP 后面对应是多台机器,因此也被成为 Virtual IP。
反向代理是工作在 HTTP 上的,具体实现可以基于 HAProxy 或 Nginx,因为反向代理能理解 HTTP 协议,所以能做非常多的事情,比如:
进行很多统一处理,比如防攻击策略、防抓取、SSL、gzip、自动性能优化等
应用层的分流策略都能在这里做,比如对 /xx 路径的请求分到 a 服务器,对 /yy 路径的请求分到 b 服务器,或者按照 cookie 进行小流量测试等
缓存,并在后端服务挂掉的时候显示友好的 404 页面
监控后端服务是否异常

3.2 Web Server 中的处理

请求经过前面的负载均衡后,将进入到对应服务器上的 Web Server,比如 Apache、Tomcat、Node.JS 等。

以 Apache 为例,在接收到请求后会交给一个独立的进程来处理,我们可以通过编写 Apache 扩展来处理,但这样开发起来太麻烦了,所以一般会调用 PHP 等脚本语言来进行处理,比如在 CGI 下就是将 HTTP 中的参数放到环境变量中,然后启动 PHP 进程来执行,或者使用 FastCGI 来预先启动进程。

3.3 进入后端语言

前面说到 Web Server 会调用后端语言进程来处理 HTTP 请求(这个说法不完全正确,有很多其它可能),那么接下来就是后端语言的处理了,目前大部分后端语言都是基于虚拟机的,如 PHP、Java、JavaScript、Python 等。

4. 服务器返回数据后浏览器如何处理?

4.1 从 01到字符

HTTP 请求返回的 HTML 传递到浏览器后,如果有 gzip 会先解压,然后接下来最重要的问题是要知道它的编码是什么,比如同样一个「中」字,在 UTF-8 编码下它的内容其实是「11100100 10111000 10101101」也就是「E4 B8 AD」,而在 GBK 下则是「11010110 11010000」,也就是「D6 D0」

4.2 外链资源的加载
4.3 JavaScript 的执行
4.4 从字符到图片
4.5 跨平台 2D 绘制库
4.6 GPU 合成

5. 浏览器将页面展现出

懒得搬了 直接上图(太细了)显示屏都出来了

在这里插入图片描述

在这里插入图片描述

总结: 大佬讲的非常细,但是底下好像还说每个阶段还可以再展开讲。如果他愿意我估计能讲一个元宇宙。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值