整体过程
-
用户输入URL地址
-
对URL地址进行DNS域名解析
-
建立TCP连接(三次握手)
-
浏览器发送HTTP请求报文
-
服务器返回HTTP响应报文
-
关闭TCP连接(四次挥手)
-
浏览器解析文档资源并渲染页面
DNS域名解析
为什么需要DNS解析域名为IP地址?
网络通讯大部分是基于TCP/IP的,而TCP/IP是基于IP地址的,所以计算机在网络上进行通讯时只能识别如“202.96.134.133”之类的IP地址,而不能认识域名。我们无法记住10个以上IP地址的网站,所以我们访问网站时,更多的是在浏览器地址栏中输入域名,就能看到所需要的页面,这是因为有一个叫“DNS服务器”的计算机自动把我们的域名“翻译”成了相应的IP地址,然后调出IP地址所对应的网页。
DNS了解一下
DNS( Domain Name System)是“域名系统”的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,它用于TCP/IP网络,它所提供的服务是用来将主机名和域名转换为IP地址的工作。
DNS解析过程
浏览器收到URL后,先去本地host文件中查找是否有对应的域名IP关系,如果有即向IP地址发起请求;如果没有,将到DNS服务器中查找。
DNS分为本地DNS服务器,根DNS服务器和各个子DNS服务器。
从浏览器到本地DNS服务器属于递归查询,而DNS服务器之间属于迭代查询。例如对www.esaonwong.com这个域名进行解析,步骤如下:
-
浏览器向本地DNS服务器发送www.esaonwong.comDNS查询报文
-
本地DNS服务器向根DNS服务器转发该报文
-
根DNS服务器解析到com后缀,告知本地DNS服务器comDNS服务器的IP地址
-
本地DNS服务器向comDNS服务器转发该报文
-
comDNS服务器解析到www.esaonwong.com后缀,告知本地DNS服务器www.esaonwong.comDNS服务器的IP地址
-
本地DNS服务器向www.esaonwong.comDNS服务器转发该报文
-
www.esaonwong.comDNS服务器解析到www.esaonwong.com后缀,告知本地DNS服务器www.esaonwong.com的IP地址
-
本地DNS服务器返回对应的IP地址给浏览器
建立TCP连接
通俗理解
TCP连接就是我们常谈的三次握手过程🤝
客户端:“你好在吗?我要给你发送东西咯~!”
服务端:“嗯嗯我在啊!你发吧~”
客户端: “嗯啊-8-”
图解
- 客户端发送连接请求报文段,将SYN位置为1,Seq为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;
- 服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置ACK为x+1;同时,自己自己还要发送SYN请求信息,将SYN位置为1,Seq为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
- 客户端收到服务器的SYN+ACK报文段。然后将ACK设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。
为什么是三次握手而不是两次,四次呢?
在谢希仁著《计算机网络》第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。在另一部经典的《计算机网络》一书中讲“三次握手”的目的是为了解决“网络中存在延迟的重复分组”的问题。
在谢希仁著《计算机网络》书中同时举了一个例子,如下:
“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”
在知乎上有个生动的比喻:
三次握手:
“喂,你听得到吗?”
“我听得到呀,你听得到我吗?”
“我能听到你,今天balabala……”
两次握手:
“喂,你听得到吗?”
“我听得到呀”
“喂喂,你听得到吗?”
“草,我听得到呀!!!!”
“你TM能不能听到我讲话啊!!喂!”
“……”
四次握手:
“喂,你听得到吗?”
“我听得到呀,你听得到我吗?”
“我能听到你,你能听到我吗?”
“……不想跟傻逼说话”
浏览器发送HTTP请求报文
(略)
服务器返回HTTP响应报文
(略)
关闭TCP连接
通俗理解
TCP连接关闭时进行四次握手过程👋
客户端:“你好,我这边没有数据要传了,我要关闭咯。”
服务端:“收到~我看一下我这边有没数据要传的。”
服务端:“我这边也没有数据要传啦,我们可以关闭连接咯~”
客户端:”ojbk~“
图解
- 主机1(可以使客户端,也可以是服务器端),设置Seq和Ack,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;
- 主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Ack为Seq加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求;
- 主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态;
- 主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。
浏览器解析文档资源并渲染页面
-
HTML解析出DOM Tree
-
CSS解析出CSSOM Tree
-
JavaScript代码由JavaScript引擎处理
-
DOM树建立后根据CSS样式进行构建内部绘图模型,生成RenderObject树
-
根据网页层次结构构建RenderLayer树,同时构建虚拟绘图上下文
-
依赖2D和3D图形库渲染成图像结果呈现在浏览器中(Painting)
我们以webkit内核浏览器渲染过程为例
HTML解析
HTML Parser的任务是将HTML标记解析成DOM Tree
CSS解析
CSS Parser将CSS解析成Style Rules,Style Rules也叫CSSOM(CSS Object Model)。
StyleRules也是一个树形结构,根据CSS文件整理出来的类似DOM Tree的树形结构
JavaScript处理
浏览器解析文档,当遇到script标签的时候,会立即解析脚本,停止解析文档(因为JS可能会改动DOM和CSS,所以继续解析会造成浪费)。
如果脚本是外部的,会等待脚本下载完毕,再继续解析文档。现在可以在script标签上增加属性 defer或者async。
脚本解析会将脚本中改变DOM和CSS的地方分别解析出来,追加到DOM Tree和Style Rules上。
布局(回流)
创建渲染树后,下一步就是布局(Layout),或者叫回流(reflow,relayout),这个过程就是通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸,将其安置在浏览器窗口的正确位置,而有些时候我们会在文档布局完成后对DOM进行修改,这时候可能需要重新进行布局,也可称其为回流,本质上还是一个布局的过程,每一个渲染对象都有一个布局或者回流方法,实现其布局或回流。
绘制(重绘)
在绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。绘制工作是使用用户界面基础组件完成的。
CSS2 规范定义了绘制流程的顺序。绘制的顺序其实就是元素进入堆栈样式上下文的顺序。这些堆栈会从后往前绘制,因此这样的顺序会影响绘制。块呈现器的堆栈顺序如下:
- 背景颜色
- 背景图片
- 边框
- 子代
- 轮廓
Reflow的成本比Repaint的成本高得多的多。DOM Tree里的每个结点都会有reflow方法,一个结点的reflow很有可能导致子结点,甚至父点以及同级结点的reflow。在一些高性能的电脑上也许还没什么,但是如果reflow发生在手机上,那么这个过程是非常痛苦和耗电的。 所以,下面这些动作有很大可能会是成本比较高的。
-
当你增加、删除、修改DOM结点时,会导致Reflow或Repaint
-
当你移动DOM的位置,或是搞个动画的时候。
-
当你修改CSS样式的时候。
-
当你Resize窗口的时候(移动端没有这个问题),或是滚动的时候。
-
当你修改网页的默认字体时。
-
注:display:none会触发reflow,而visibility:hidden只会触发repaint,因为没有发现位置变化。
基本上来说,reflow有如下的几个原因:
-
Initial。网页初始化的时候。
-
Incremental。一些Javascript在操作DOM Tree时。
-
Resize。其些元件的尺寸变了。
-
StyleChange。如果CSS的属性发生变化了。
-
Dirty。几个Incremental的reflow发生在同一个frame的子树上。
参考文章
(完)
网友评论