0%

HTML,CSS和Js如何变成页面

构建DOM树

将HTML转换为浏览器能够理解的DOM树结构

样式计算

生成DOM树后,根据CSS样式表,计算出DOM树中所有节点的样式

布局阶段

1.构建布局树:

  • 遍历DOM树中所有可见结点,并把这些结点加到布局中
  • 不可见的结点会被布局树忽略,如head标签下大雾全部内容,以及display:none的元素

2.布局计算

计算布局树中节点的坐标位置

分层

1拥有层叠上下文属性的元素会被提升为单独的一层

2需要剪裁的地方也会被创建为图层

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style>
div {
width: 200;
height: 200;
overflow:auto;
background: gray;
}
</style>
<body>
<div >
<p>所以元素有了层叠上下文的属性或者需要被剪裁,那么就会被提升成为单独一层,你可以参看下图:</p>
<p>从上图我们可以看到,document层上有A和B层,而B层之上又有两个图层。这些图层组织在一起也是一颗树状结构。</p>
<p>图层树是基于布局树来创建的,为了找出哪些元素需要在哪些层中,渲染引擎会遍历布局树来创建层树(Update LayerTree)。</p>
</div>
</body>

当div里面文字内容过多,文字显示区域超出200*200面积,产生了剪裁,渲染引擎会把裁剪文字内容的一部分用于显示在div区域,出现裁剪情况时,渲染引擎会为文字不烦单独创建一个层,如果出现滚动条,滚动条也会被提升为单独的层

图层绘制

图层树构建完成后,渲染引擎会对图层树中每个图层进行绘制

渲染引擎会把图层的绘制拆分成很多小的绘制指令,然后把这些指令按照顺序组成一个待绘制列表

栅格化操作

绘制列表是用来记录绘制顺序和绘制指令的列表,实际上绘制操作是由渲染引擎中的合成线程完成的,当图层的绘制列表准备好后,主线程会把绘制列表提交给合成线程,合成线程会把图层划分为图块,这些图块的大小通常为256x256或512*x512,合成线程按照视口附近的图块优先生成位图,实际生成的位图由栅格化来执行,栅格化就是将图块转为位图,渲染进程维护了一个栅格化的线程池,所有的图块栅格化都是在线程池内执行。使用GPU生成位图的过程叫做快速栅格化。

合成和显示

图块栅格化完成后,合成线程就会生成一个绘制图块命令”DrawQuad”,将该命令提交给浏览器进程,浏览器进程有一个viz组件,用来接收合成线程发过来的DrawQuad命令,根据该命令,将页面内容绘制到内存中,最后将内存显示在屏幕上

渲染流程总结:

  • 渲染进程将HTML内容转换为浏览器能读懂的DOM树结构
  • 渲染引擎将CSS样式表转化为浏览器能理解的styleSheets,计算出DOM结点样式
  • 创建布局树,并计算元素的布局信息
  • 对布局树进行分层,并生成分层树
  • 为每个图层生成绘制列表,并将其提交到合成线程
  • 合成线程将图层分层图块,并在光栅化线程池中将图块转为位图
  • 合成线程发送绘制图块命令DrawQuad给浏览器进程
  • 浏览器进程根据DrawQuad消息生成页面,并显示到显示器上

参考链接:

https://blog.poetries.top/browser-working-principle/guide/part1/lesson06.html#_1-%E6%9B%B4%E6%96%B0%E4%BA%86%E5%85%83%E7%B4%A0%E7%9A%84%E5%87%A0%E4%BD%95%E5%B1%9E%E6%80%A7%EF%BC%88%E9%87%8D%E6%8E%92%EF%BC%89