从浏览器输入URL到页面显示的过程

从浏览器地址栏输入url到显示页面的步骤:

目录

1.概述

浏览器根据请求的URL交给DNS域名解析器,找到真实IP,向服务器发起请求;
三次握手建立连接,服务器交给后台处理完成后返回数据,浏览器接收文件(HTML,JS,CSS,图像等),数据传入完成后四次挥手断开连接。
浏览器对加载到的资源(HTML,JS,CSS等)进行语法解析,建立相应的内部数据结构。
载入解析到的资源文件,渲染页面,完成。

2.DNS域名解析

DNS域名解析过程又分为七步:
1.浏览器缓存
2.系统缓存
3,路由缓存
4.ISP DNS缓存
5,DNS递归查询

2.1第一大步:先查缓存

2.2.1浏览器缓存
当用户通过浏览器访问域名时,浏览器首先会在自己的缓存中的查找是否有该域名对应的IP地址。这个过程中浏览器有强缓存行为和协商缓存行为。
强缓存:浏览器直接从本地缓存中获取了数据,不与服务器进行交互;
协商缓存:浏览器发送请求到服务器,服务器判断是否可使用本地缓存。

2.2.2系统缓存
当浏览器缓存中无域名对应IP则会自动检查用户计算机系统Host缓存是否有该域名对应的IP。windows下该文件存在于C:\Windows\System32\drivers\etc

2.2.3路由器缓存
当浏览器及系统缓存中均无域名对应IP则进入路由器缓存中检查,以上三步均为客户端的DNS缓存。

2.24DNS服务器缓存/ISP(互联网服务提供商)缓存。

2.2第二大步:DNS服务器查找

关于查找,我们上一篇内容已经讲的很清楚了,不知道的小伙伴先去看看我写的上一篇关于DNS协议的内容。
另外:DNS服务器查找使用的是UDP协议。因为UDP快,UDO的DNS协议传输内容不能超过512字节,不过客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。
补充:DNS服务器查找往往采用:递归查询或迭代查询。上篇内容中我们讲到的是迭代查询,当然这也是一种常用的方式,由于递归查询对于被查询的域名的服务器附带太大,所以通常情况下,从请求主机到本地域名服务器查询时递归查询,而其余的查询都是迭代查询。

3.三次握手与四次挥手

更详细的内容请看我之前发过的那篇关于TCP连接的文章,这里就不在赘述了。

4. DOM,CSSOM,渲染树的构建,渲染与绘制

4.0浏览器渲染过程(概述)

1.浏览器会解析三个东西:
一是HTML/SCG/XHTML,HTML字符串描述了一个页面的结构,浏览器会把HTML结构字符串解析转换DOM树结构。
二是CSS,解析CSS会产生CSS规则书,它和DOM结构比较像。
三是Javascript脚本,等到Javascript脚本文件加载后,通过DOMAPI和CSSDOM API来操作DOM Tree和CSS Rule Tree。

2.解析完成后,浏览器引擎会通过DOM Tree和CSS Rule Tree来构造Rendering Tree.

  • Rendering Three渲染树并不等同于DOM树,渲染数只会包括需要显示的节点和这些节点的样式信息。
  • CSS的 Rule Tree主要是为了完成匹配并把CSS Rule附加到 Rendering Tree的每个Element。
  • 然后,计算每个Frame的位置,这又叫layout和reflow过程。

3 .最后通过调用操作系统的Native GUI的API绘制。

4.1构建DOM

浏览器会遵守一套步骤将HTML文件转换为DOM数树,宏观上,可以分为几个步骤:
在这里插入图片描述

  • 浏览器接收到字节数据之后,会根据文件的指定编码(例如 UTF-8)将他们转换成字符串。也就是我们写的代码。
  • 将字符串转换成 Token。Token中辉表示当前 Token是“开始标签”或是“结束标签”亦或是“文本信息”。那么这时候你定会有疑问,节点与节点之间的关系如何维护?
    事实上,这就是Token要标识“起始标签”和“结束标签”等标识的作用,例如“title ”Token的起始标签和结束标签之间的节点肯定是属于“head”的子节点。
    在这里插入图片描述
    上图中给了节点之间的关系,例如:“Hello” Token位于“title”开始标签与“title”结束标签之间,表明“Hello”Token是“title”Token的子节点。同理“title”Token是“head”Token的子节点。
  • 生成节点对象并构建DOM
  • 事实上,苟江DOM的过程中,不是等所有的Token都转换完后再去生成节点对象,而是一边生成Token一边消耗Token来生成节点对象。换句话说,每个Token被生成后,会立刻消耗这个Token创建出节点对象。注意:带有结束表示标签的Token不会创建节点对象。
  • 接下来我们举个例子,假设有段HTML文本:
<body>
<div>
<h1>Web page parsing</h1>
<p>This is an example Web page.</p>
</div>
</body>
</html>
上面这段HTML会解析成这样:

在这里插入图片描述

4.2构建CSSOM

DOM会捕获页面的内容,但浏览器还需要知道页面如何展示,所以需要构建CSSOM。

构建CSSOM的过程与构建DOM的过程非常相似,当浏览器接收到一段CSS,浏览器首先要做的是识别出Token,然后构建节点并生成CSSOM
在这里插入图片描述
在这一过程中,浏览器会确定下每一个节点的样式到底是什么,并且这一过程其实是很消耗资源的。因为样式你可以自行设置给某个节点,也可以通过继承获得。在这一过程中,浏览器得递归 CSSOM 树,然后确定具体的元素到底是什么样式。
注意:CSS匹配HTML元素是一个相当复杂和有性能问题的事情。所以,DOM树要小,CSS尽量用id和class,千万不要过渡层叠下去。

4.3 构建渲染树

当我们生成DOM树和CSSOM树以后,就需要将这两棵树组合为渲染树
在这里插入图片描述
在这一过程中,不是简单的将两者合并就行了。渲染树只会包括需要显示的节点和这些节点的样式信息,如果某个节点是 display: none 的,那么就不会在渲染树中显示。
这时候就会有两个内部数据结构----DOM树和渲染树。DOM树表示页面结构就,渲染树表示DOM节点如何显示。DOM树中的每一个需要显示的节点在渲染树中至少存在一个对应的节点。
一旦DOM树和渲染树构建完成,浏览器就开始显示(绘制)页面元素。

我们或许有个疑惑:浏览器如果渲染过程中遇到JS文件怎么处理

渲染过程中,如果遇script标签就停止渲染,执行 JS 代码。因为浏览器有GUI渲染线程与JS引擎线程,为了防止渲染出现不可预期的结果,这两个线程是互斥的关系。 JavaScript的加载、解析与执行会阻塞DOM的构建,也就是说,在构建DOM时,HTML解析器若遇到了JavaScript,那么它会暂停构建DOM,将控制权移交给JavaScript引擎,等JavaScript引擎运行完毕,浏览器再从中断的地方恢复DOM构建。
也就是说,如果你想首屏渲染的越快,就越不应该在首屏就加载 JS 文件,这也是都建议将 script 标签放在 body 标签底部的原因。当然在当下,并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性。

JS文件不只是阻塞DOM的构建,它会导致CSSOM也阻塞DOM的构建。
原本DOM和CSSOM的构建是互不影响,井水不犯河水,但是一旦引入了JavaScript,CSSOM也开始阻塞DOM的构建,只有CSSOM构建完毕后,DOM再恢复DOM构建。
这是什么情况?
这是因为JavaScript不只是可以改DOM,它还可以更改样式,也就是它可以更改CSSOM。因为不完整的CSSOM是无法使用的,如果JavaScript想访问CSSOM并更改它,那么在执行JavaScript时,必须要能拿到完整的CSSOM。所以就导致了一个现象,如果浏览器尚未完成CSSOM的下载和构建,而我们却想在此时运行脚本,那么浏览器将延迟脚本执行和DOM构建,直至其完成CSSOM的下载和构建。也就是说,在这种情况下,浏览器会先下载和构建CSSOM,然后再执行JavaScript,最后在继续构建DOM。

在这里插入图片描述

4.4 布局与绘制

当浏览器生成渲染树以后,就会根据渲染树来进行布局(也可以叫做回流)。这一阶段浏览器要做的事情是要弄清楚各个节点在页面中的确切位置和大小。通常这一行为也被称为“自动重排”。
布局流程的输出是一个“盒模型”,它会精确地捕获每个元素在视口内的确切位置和尺寸,所有相对测量值都将转换为屏幕上的绝对像素。
布局完成后,浏览器会立即发出“Paint Setup”和“Paint”事件,将渲染树转换成屏幕上的像素。

4.5重绘和重排

渲染的基本流程就是这样:
在这里插入图片描述

  • 重绘:当我们对 DOM 的修改导致了样式的变化、却并未影响其几何属性(比如修改了颜色或背景色)时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式。
  • 重排:当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为重排。完成重排后,浏览器会重新绘制受影响的部分到屏幕,该过程称为重绘。
    -我们知道,当网页生成的时候,至少会渲染一次。在用户访问的过程中,还会不断重新渲染。重新渲染会重复重排+重绘或者只有重绘。 重排(回流)会发生重绘,重绘不一定会引发重排(回流)。重绘和回流会在我们设置节点样式时频繁出现,同时也会很大程度上影响性能。回流所需的成本比重绘高的多,改变父节点里的子节点很可能会导致父节点的一系列回流。

常见引起重排(回流)属性和方法:
任何会==改变元素几何信息(元素的位置和尺寸大小)==的操作,都会触发回流,
1.添加或者删除可见的DOM元素;
2.元素尺寸改变——边距、填充、边框、宽度和高度
3.内容变化,比如用户在input框中输入文字
4.浏览器窗口尺寸改变——resize事件发生时
5.计算 offsetWidth 和 offsetHeight 属性
6.设置 style 属性的值

常见的引重绘属性和方法在这里插入图片描述
如何减少重排,重绘
1.同一个DOM的的多个属性改变可以写在一起(减少DOM访问)
2.使用 visibility 替换 display: none ,因为前者只会引起重绘,后者会引发重排(display:none的时候渲染树上没有节点信息)
3.不要把节点的属性值放在一个循环里当成循环里的变量。

	 for(let i = 0; i < 1000; i++) {
		// 获取 offsetTop 会导致回流,因为需要去获取正确的值
		console.log(document.querySelector('.test').style.offsetTop)
	}

4.不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局
5.将频繁重绘或者回流的节点的position属性设置为absolute,fixed,这样此元素就脱离的文档流,它的变化不会影响到其他元素。例如有动画效果的元素设置为绝对定位。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值