引言:
-
当在浏览器的地址栏输入url,或者从外部点击链接打开浏览器,到整个页面的加载完成后的呈现,这个过程涉及网络通信、数据解析、资源加载、DOM构建、CSS渲染、JavaScript执行等多个环节的协同工作,了解这一过程,对于我们前端小伙伴们了解如何提升用户体验、加快网页加载速度还算有那么一乃乃用的。
-
之前看过很多篇关于类似的文章,今天想站在巨人们的肩膀上,聊一聊的我对这一过程的理解(觉得说得不好,轻点喷,小心口水流下来)
从输入URL到看到页面显示的全过程涉及多个关键步骤和复杂的技术细节,主要分为以下步骤
1、url解析
- 首先浏览器会对地址栏的中的url进行解析,校验其合法性(检查URL是否包含协议、域名、路径等必要部分,并且这些部分的格式是否正确),并提取出协议(http、https)、主机名、路径(/xxxx)等信息
2、cdn解析
- 浏览器会将解析出来的主机名,在浏览器本地CDN缓存中查找是否存在其对应的IP地址,如果有,则返回IP地址,没有则进行下一步
- 如果浏览器本地缓存中不存在该域名对应的IP地址,则浏览器会进一步查看操作系统的缓存
- 如果系统缓存也没有,则会进一步去查找路由器缓存
- 如果上述缓存中均没有找到对应IP,则会向DNS服务器发送请求,获取对应的IP地址
3、建立TCP连接
- 浏览器会通过IP地址与端口号与服务器建立TCP连接,这个过程通过三次握手完成,确保双方能够正常通讯
-
客户端(浏览器)向服务端发送一段SYN报文,表示请求连接,此时客户端处于SYN_SENT状态
-
服务器接收到客户端发送来的SYN报文后,会发送一个ACK/SYN报文作为应答,表示同意连接,同时服务器处于SYN_RCVD状态
-
客户端收到服务端回传的ACK/SYN报文后,会再发送一个ACK报文,表示收到服务端回传的报文,此时客户端处于ESTABLISHED状态,服务端收到回传的报文后,状态也会更新成ESTABLISHED,至此,连接建立完成
-
4、发送HTTP请求
- 连接建立完成后,浏览器会构建http请求的报文,包括请求行(请求方法、URL等)请求头(cookie、user_Agent)、请求体(对于POST请求)
- 服务端接收到请求后,会进行一系列处理,如(数据库读取、业务逻辑处理、生成动态内容等),处理完成之后,服务器会将处理完成的结果分装成HTTP响应报文,返回给客户端(浏览器),响应报文的具体内容包括:状态码、响应头(content-type、Content-Length)、响应体(页面将要显示的数据信息)
5、浏览器解析,页面渲染
- 浏览器在接收到服务端响应后,会解析响应报文并渲染页面,主要分为以下几个步骤
- HTML解析:浏览器使用HTML解析器,将HTML文档解析成DOM树
- css解析:浏览器使用CSS解析器将css文件解析成样式规则
- 构建渲染:将解析完成的DOM树与于CSSOM树合并,生成渲染树,渲染树里面包含了页面可视化渲染表示
- 布局与绘制:浏览器根据渲染树,确定每个元素的位置与大小,进而绘制页面
- 执行js代码:如果页面包含js代码,会执行js代码,js代码操作DOM更新,处理用户交互、发起异步请求
6、加载其他资源
- HTML文档中可能引用了其他资源,比如图片、字体、第三方库等,浏览器会根据需要,请求对应资源,并重复经历TCP连接、http请求、数据响应等过程
7、关闭TCP连接
- 当页面加载完成后,浏览器会通过四次挥手释放TCP连接,这个过程确保了客户端子服务端之间数据传输的结束,并释放了相关资源
-
第一次挥手,浏览器会向服务端发送一个FIN报文(连接释放报文),并停止发送数据,主动关闭TCP连接,此时客户端处于FIN_WAIF1状态
-
第二次挥手,服务端在接收到连接释放报文后,会发送ACK报文作(确认报文)为响应,这段报文的确认号被设置为客户端FIN报文段的序列号+1,表示已经收到客户端连接释放报文,此时服务端的状态处于CLOSE_WAIT,但此时,服务端仍可以向客户端发送数据
-
第三次挥手,当服务端也准备好关闭连接时,服务端会向客户端发送一段FIN报文,此报文不包含任何数据,只是用来高数客户端想要关闭连接
-
第四次挥手,客户端收到服务端发来的FIN报文之后,会返回一个ACK报文,作为最终确认,这个报文段确认号被设置为服务端FIN报文段的序列号+1,表示客户端已经收到服务端的FIN报文,至此四次挥手结束,TCP请求关闭
-