这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。
大家好,我是小杜杜,今天聊聊一个老生常谈的话题:浏览器的渲染过程,在面试的过程中,这个问题也是常考题,通常面试官会问:从输入一个url地址到浏览器完成渲染的整个过程发生了什么?
渲染的过程实际上非常复杂,我们需要了解并熟知其过程即可
发生的过程
当浏览器地址栏输入URL并回车的过程依次是(建议熟记~):
- 浏览器查找当前URL是否存在缓存,并比较缓存是否过期
- DNS 解析 URL 对应的 IP
- 根据 IP 建立 TCP 链接(三次握手)
- 发送 http 请求
- 服务器处理请求,浏览器接受 HTTP 响应
- 浏览器解析并渲染页面
- 关闭 TCP 链接(四次握手)
查找缓存
浏览器首先会去查找缓存,就好像你要去一个地方,首先要想这个地方去过没有,如果去过直接过去,没去过则按照导航一步一步过去,那么浏览器也是一样的。
浏览器先查看浏览器缓存 => 系统缓存 => 路由缓存中是否有该地址页面,如果有则直接显示页面内容,反之则进行下一步。
- 浏览器缓存:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求;
- 系统缓存:如果在浏览器缓存中不包含这个记录,则会使系统调用操作系统,获取操作系统的记录(保存最近的DNS查询缓存);
- 路由器缓存:如果上述两个步骤均不能成功获取DNS记录,继续搜索路由器缓存;
最后,三个缓存都为寻找到,则继续想ISP搜索
DNS解析
DNS解析一般指域名解析,是把域名所指向网站空间IP,也就是数字地址,而域名解析的主要作用就是便于记忆。
那么为什么需要解析呢?
因为在网络通信中,大部分是机遇 TCP/IP 的,而 TCP/IP 是基于 IP 地址的,所以计算机在网络上只能识别IP地址(如:202.97.111.101),而不能识别域名
TCP 链接
之后会根据IP进行TCP链接,通过 IP 和默认的80端口,和服务器简历TCP链接
具体如何链接可以看看这篇文章 TCP三次握手和四次挥手深入实践
浏览器是如何解析并渲染页面
我们知道执行 JS 有一个 JS 引擎,那么执行渲染也有一个渲染引擎。同样,渲染引擎在不同的浏览器中也不是都相同的。
比如在 Firefox 中叫做 Gecko,在 Chrome 和 Safari 中都是基于 WebKit 开发的。
过程图:
我们从图中可以看到
- 首先将 HTML 通过 HTMl parser 转化为
DOM tree, 同时 css 通过 ccs 规则和css解析器转化为CSSDOM tree - 然后将两者进行合成,形成最终的
render tree(注意:此时并不知道html的具体内容,也不知道具体位置是什么) - 然后通过
layout就可以精确计算到要显示的这些 dom 真正的宽高,位置颜色,最后开始paint,画图,把内容呈现出来
如何将HTML转化为DOM树
我们知道,我们写代码的时候会分为 HTML、CSS、JS 文件,也就是字符串,但计算机硬件是不理解这些字符串的,实际上,在网络传输中的内容实际上都是 0 和 1 的字节数据。
当浏览器拿到这些字节数据的时候,换转化成对应的字符串,也就是我们写的代码。
之后浏览器会将这些字符串通过此法分析转化为标记(token),这一过程叫做标记化
那么为什么要进行标记呢?原因是最终会把代码拆分成一块一块的,并且给这些内容打上标记,便于理解这块代码是什么意思。
如:
当标记结束后,紧接着会转化为 Node,然后这些Node会形成一个DOM树
总结下所进行的过程:字节数据 => 字符串 => Token => Node => DOM
如何将CSS转化为CSSDOM树
跟HTML转化为DOM树的过程非常类似,其过程为:字节数据 => 字符串 => Token => Node => CSSDOM
注意这一过程浏览器会确定下每一个节点的样式到底是什么,并且这一过程其实是很消耗资源的。
举个简单的例子:
<div>
<p> <span> </span> </p>
</div>
//渲染样式,分别对 span 进行渲染
// 第一种
span{
color: red
}
//第二种
div > p > span{
color: red
}
- 对于第一种而言,浏览器只要找到对应的span标签即可
- 对于第二种而言,浏览器需要找到所有的span标签,再找到span标签的p标签,再找到之上的div标签,然后给符合这种规则的标签设置颜色,这样的过程就会变得很复杂
如何渲染为最终的render tree
当我门拿到 DOM Tree 和 CSSDOM Tree时,要将两棵树进行结合,这一过程并不是简简单单的将两者合并。
需要注意的是
- Render Tree 只包含需要显示的节点和这些节点的样式信息,比如样式为
display:none的,并不再Render Tree中展示 - 当浏览器生成渲染树以后,就会根据渲染树来进行布局(也可以叫做
回流),然后调用 GPU 绘制,合成图层,显示在屏幕上。(这一部分的内容过于底层,还涉及到硬件相关的知识)
End
致此,有关浏览器渲染就已经完成了,相信各位小伙伴已经了解其过程了,喜欢的点个赞👍🏻支持下吧(● ̄(エ) ̄●)