跳到主要内容

大家好,我是小杜杜,今天聊聊一个老生常谈的话题:浏览器的渲染过程,在面试的过程中,这个问题也是常考题,通常面试官会问:从输入一个 url 地址到浏览器完成渲染的整个过程发生了什么?

渲染的过程实际上非常复杂,我们需要了解并熟知其过程即可

发生的过程

当浏览器地址栏输入 URL 并回车的过程依次是(建议熟记~):

  1. 浏览器查找当前 URL 是否存在缓存,并比较缓存是否过期
  2. DNS 解析 URL 对应的 IP
  3. 根据 IP 建立 TCP 链接(三次握手)
  4. 发送 http 请求
  5. 服务器处理请求,浏览器接受 HTTP 响应
  6. 浏览器解析并渲染页面
  7. 关闭 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 开发的。

过程图:

DOM.png

我们从图中可以看到

  • 首先将 HTML 通过 HTMl parser 转化为 DOM tree, 同时 css 通过 ccs 规则和 css 解析器转化为 CSSDOM tree
  • 然后将两者进行合成,形成最终的 render tree(注意:此时并不知道 html 的具体内容,也不知道具体位置是什么)
  • 然后通过 layout 就可以精确计算到要显示的这些 dom 真正的宽高,位置颜色,最后开始 paint,画图,把内容呈现出来

如何将 HTML 转化为 DOM 树

我们知道,我们写代码的时候会分为 HTML、CSS、JS 文件,也就是字符串,但计算机硬件是不理解这些字符串的,实际上,在网络传输中的内容实际上都是 0 和 1 的字节数据

当浏览器拿到这些字节数据的时候,换转化成对应的字符串,也就是我们写的代码。

之后浏览器会将这些字符串通过此法分析转化为标记(token),这一过程叫做标记化

那么为什么要进行标记呢?原因是最终会把代码拆分成一块一块的,并且给这些内容打上标记,便于理解这块代码是什么意思。

如:

image.png

当标记结束后,紧接着会转化为 Node,然后这些 Node 会形成一个 DOM 树

image.png

总结下所进行的过程:字节数据 => 字符串 => 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 时,要将两棵树进行结合,这一过程并不是简简单单的将两者合并。

image.png

需要注意的是

  • Render Tree 只包含需要显示的节点和这些节点的样式信息,比如样式为display:none的,并不再Render Tree中展示
  • 当浏览器生成渲染树以后,就会根据渲染树来进行布局(也可以叫做回流),然后调用 GPU 绘制,合成图层,显示在屏幕上。(这一部分的内容过于底层,还涉及到硬件相关的知识)

End

致此,有关浏览器渲染就已经完成了,相信各位小伙伴已经了解其过程了,喜欢的点个赞 👍🏻 支持下吧(●  ̄(エ) ̄ ●)

来自

作者:小杜杜

链接:https://juejin.cn/post/7082309539688628261

来源:稀土掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。