用户输入网址到页面返回都发生了什么?

举报
猫先生c 发表于 2023/09/28 09:20:50 2023/09/28
【摘要】 🐱 个人主页:不叫猫先生,公众号:前端舵手🙋‍♂️ 作者简介:2022年度博客之星前端领域TOP 2,前端领域优质作者、阿里云专家博主,专注于前端各领域技术,共同学习共同进步,一起加油呀!💫优质专栏:vue3+vite+typeScript从入门到实践📢 资料领取:前端进阶资料可以找我免费领取🔥 摸鱼学习交流:我们的宗旨是在「工作中摸鱼,摸鱼中进步」,期待大佬一起来摸鱼(文末有我w...

🐱 个人主页:不叫猫先生,公众号:前端舵手
🙋‍♂️ 作者简介:2022年度博客之星前端领域TOP 2,前端领域优质作者、阿里云专家博主,专注于前端各领域技术,共同学习共同进步,一起加油呀!
💫优质专栏:vue3+vite+typeScript从入门到实践
📢 资料领取:前端进阶资料可以找我免费领取
🔥 摸鱼学习交流:我们的宗旨是在「工作中摸鱼,摸鱼中进步」,期待大佬一起来摸鱼(文末有我wx或者私信)

在这里插入图片描述
@TOC

用户输入网址到页面返回都发生了什么?

1、分析地址栏中URL

浏览器做的第一步就是会解析URL得到里面的参数,分析域名是否规范,并将域名和需要的请求的资源分离开来,从而了解需要请求的是哪个服务器,请求的是服务器上的什么资源等等

2、DNS域名解析

浏览器将网址转换成对应的IP地址

  • ==本地电脑会检查浏览器缓存是否有这个域名解析过的IP地址,如果有,解析完成==

  • ==浏览器缓存中没有的话,就会在操作系统缓存中查找==。操作系统会有一个域名解析的过程。Linux中可以通过/etc/hosts文件来设置;在windows中可以通过配置C:\Windows\System32\drivers\etc\hosts文件来设置,用户可以将任何域名解析到任何能够访问的IP地址

  • ==如果前两种方式都没找到,操作系统会把这个域名发送给这个本地DNS服务器==,一个完整的内网通常都会配置本地DNS服务器,一般都会缓存域名解析结果。操作系统和本地域名服务器之间的查询方式是递归查询。

  • ==本地域名DNS服务器仍然没有命中,就直接到根DNS服务器请求解析==。根DNS服务器返回给本地DNS域名服务器一个顶级DNS服务器地址,它是国际顶级域名服务器,如.com、.cn、.org等,全球只有13台左右

本地域名服务器和其他域名服务器之间的查询方式是迭代查询,防止根域名服务器压力过大,通过以下方式进行迭代查询:

  • 首先本地域名服务器向根域名服务器发起请求,根域名服务器是最高层次的,它并不会直接指明这个域名对应的 IP 地址,而是返回顶级域名服务器的地址
  • 本地域名服务器拿到这个顶级域名服务器的地址后,就向其发起请求,获取权限域名服务器的地址
  • 本地域名服务器根据权限域名服务器的地址向其发起请求,最终得到该域名对应的IP地址

注意:
本地域名服务器和其他域名服务器之间的查询方式是迭代查询,防止根域名服务器压力过大
操作系统和本地域名服务器之间的查询方式是递归查询。

也就是说:接受请求的顶级DNS服务器查找并返回此域名对应的Name Server域名服务器的地址,Name Server服务器就是我要访问的网站域名提供商的服务器,其实该域名的解析任务就是由域名提供商的服务器来完成。 (比如访问www.baidu.com,而这个域名是从A公司注册获得的,那么A公司上的服务器就会有www.baidu.com的相关信息)。Name Server服务器会查询存储的域名和IP的映射关系表,再把查询出来的域名和IP地址等等信息,连同一个TTL值返回给本地DNS服务器。

  • 本地域名服务器将得到的该域名对应的IP和TTL值返回给操作系统,同时会缓存这个域名和IP的对应关系

  • 操作系统将 IP 地址返回给浏览器,同时自己也将IP地址缓存起来

  • 至此,浏览器就得到了域名对应的 IP地址,并将IP地址缓存起来

  • 域名解析过程结束

==DNS域名解析是一个复杂的过程,在实际的DNS解析过程中,可能还不止这些。==

3、建立TCP链接

浏览器和服务器之间会简历一个TCP三次握手的连接,用于传输数据。
==TCP通信需要确保双方都具有数据收发的能力,得到ACK响应则认为对方具有数据收发的能力,因此双方都要发送SYN确保对方具有通信的能力。==

  • 第一次握手是客户端发送SYN,服务端接收,服务端得出客户端的发送能力和服务端的接收能力都正常
  • 第二次握手是服务端发送SYN+ACK,客户端接收,客户端得出客户端发送接收能力正常,服务端发送接收能力也都正常,但是此时服务器并不能确认客户端的接收能力是否正常
  • 第三次握手客户端发送ACK,服务器接收,服务端才能得出客户端发送接收能力正常,服务端自己发送接收能力也都正常。

4、HTTP请求

浏览器向服务器发送一个HTTP请求报文,包括请求方法、请求头、请求体等信息。

5、HTTP响应

服务器接受到请求后,根据请求内容进行处理,返回一个HTTP响应报文,包括状态码、响应头、响应体等。

6、渲染页面

浏览器根据响应报文的内容,解析HTML、CSS、JS等资源,构建DOM树、CSSOM树、渲染树,然后进行布局、绘制、合成等步骤,最终显示在页面

7、TCP断开

浏览器和服务器之间断开一个TCP四次挥手的连接,释放资源。

  • 客户端发送断开TCP连接请求的FIN 报文,报文中会指定一个序列号
  • 服务端会回复客户端发送的TCP断开请求报文,服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文
  • 服务端在回复完客户端的TCP断开请求后,不会马上进行TCP连接的断开,服务端会先确保断开前,所有传输到A的数据是否已经传输完毕,一旦确认传输数据完毕,和和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号
  • 客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值

从浏览器收到第一个字节起到页面渲染完成,做了什么?

1、构建DOM树

浏览器根据HTML文档中的内容,创建DOM节点,形成层级关系,构成DOM树

2、构建CSSOM树

浏览器根据CSS样式表中的内容,创建CSS规则,并形成层级关系,构成CSSOM树。
注意:==DOM的解析和CSSOM的解析是一个并行的过程。两者互不影响。两者解析完成之后,会合并生成render tree,之后就是layout(布局)和paint(绘制)阶段,渲染到页面中。==

3、构建渲染树

浏览器将DOM树和CSSOM树结合起来,生成渲染树,可以知道每个节点会应用什么样式的数据结构。这个结合的过程就是遍历整个 DOM 树,然后在 CSSOM 树里查询到匹配的样式。

4、布局

此时已经有了需要渲染的所有节点之间的结构关系及其样式信息。接下来就需要进行页面的布局。通过计算渲染树上每个节点的样式,就能得出来每个元素所占空间的大小和位置。当有了所有元素的大小和位置后,就可以在浏览器的页面区域里去绘制元素的边框了,这个过程就是布局。
这个过程中,浏览器对渲染树进行遍历,将元素间嵌套关系以盒模型的形式写入文档流。

5、绘制

  • 构建图层
    页面上可能有很多复杂的场景,比如3D变化、页面滚动、使用z-index进行z轴的排序等。所以,为了实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树
  • 绘制图层
    在完成图层树的构建之后,渲染引擎会对图层树中的每个图层进行绘制。渲染引擎在绘制图层时,会把一个图层的绘制分成很多绘制指令,然后把这些指令按照顺序组成一个待绘制的列表。
    绘制列表只是用来记录绘制顺序和绘制指令的列表,而绘制操作是由渲染引擎中的合成线程来完成的。当图层绘制列表准备好之后,主线程会把该绘制列表提交给合成线程。

注意:合成操作是在合成线程上完成的,所以,在执行合成操作时并不会影响到主线程的执行。

很多情况下,图层可能很大,比如一篇长文章,需要滚动很久才能到底,但是用户只能看到视口的内容,所以没必要把整个图层都绘制出来。因此,合成线程会将图层划分为图块,这些图块的大小通常是 256x256 或者 512x512。合成线程会优先将视口附近的图块生成位图。实际生成位图的操作是在光栅化阶段来执行的,所谓的光栅化就是按照绘制列表中的指令生成图片。

6、显示

当所有的图块都被光栅化之后,合成线程就会生成一个绘制图块的命令,浏览器相关进程收到这个指令之后,就会将其页面内容绘制在内存中,最后将内存显示在屏幕上,这样就完成了页面的绘制。

这个过程可能会受到JavaScript的影响,比如遇到非异步的JS代码,会暂停DOM树和CSSOM树的构建,优先执行JS,以为JS代码可能会修改或者访问DOM和CSSOM

重排和重绘

渲染树是动态构建的,所以,DOM节点和CSS节点的改动都可能会造成渲染树的重新构建。渲染树的改动就会造成页面的重排或者重绘

1、重排

当我们的操作引发了 DOM 树中几何尺寸的变化(改变元素的大小、位置、布局方式等),这时渲染树里有改动的节点和它影响的节点都要重新计算。这个过程就叫做重排,也称为回流。在改动发生时,要重新经历页面渲染的整个流程。

页面首次渲染
浏览器窗口大小变化
元素内容变化
元素尺寸变化
元素字体变化
激活CSS伪类
添加/删除可见的DOM元素

在发生重排时,由于浏览器渲染页面是基于流式布局的,所以会导致周围DOM元素重新排列。

  • 全局:从根节点开始对整个渲染树进行重新布局
  • 局部:从渲染树的某个部分或者一个对象进行重新布局。

2、重绘

当对 DOM 的修改导致了样式的变化、但未影响其几何属性(比如修改颜色、背景色)时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式(会跳过重排环节),这个过程叫做重绘。简单来说,重绘是由对元素绘制属性的修改引发的。
当我们修改元素绘制属性时,页面布局阶段不会执行,因为并没有引起几何位置的变换,所以就直接进入了绘制阶段,然后执行之后的一系列子阶段。相较于重排操作,重绘省去了布局和分层阶段,所以执行效率会比重排操作要高一些。

color
background
visibility
box-shadow
border-radius

当触发重排时,一定会触发重绘,但是重绘不一定会引发重排。

3、重排优化方式

  • 尽量使用CSS3动画,因为可以调用GPU进行渲染
  • CSS表达式
  • 将DOM的多个读操作(或者写操作)放在一起,而不是读写操作穿插着写
  • 避免频繁操作DOM,可以创建一个文档片段documentFragment,在它上面进行所有的DOM操作,最后再添加到文档中

浏览器针对页面的回流与重绘,进行了自身的优化——渲染队列, 浏览器会将所有的回流、重绘的操作放在一个队列中,当队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会对队列进行批处理。这样就会让多次的回流、重绘变成一次回流重绘。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。