浏览器渲染原理

当我们访问网站时,通过网络请求得到HTML文档,然后开启一个渲染任务。

既:浏览器开启一个渲染进程,在渲染进程中有一个渲染主线程。在事件循环的作用下,开启渲染流程。

渲染流程:

A. 解析HTML文档。

通过网络请求得到的HTML文档实际是一个字符串文档

渲染,可以想象通过render(html)解析html。

   1.在解析的过程中,会先预解析外部引用的css js资源,进行下载。

   2.然后开始从头解析HTML文档,遇到CSS就解析CSS,遇到JS就解析JS。

  •  遇到<link>引用外部css资源,若预加载没有下载完成,渲染线程会跳过,继续解析后面

        的HTML内容。这是CSS不会阻塞HTML解析的原因。

  •  遇到<script>引用外部JS资源,则会等待其下载完成后,解析并执行JS代码后,才继续解析

        后面的HTML内容。这是JS会阻塞HTML解析的原因。

        (因为JS代码可能会对之前已经解析的HTML结构或CSS样式进行修改)

B. 样式计算

        解析完成,得到DOM树和CSSOM树。通过样式计算,得到计算样式后的DOM树。(把DOM树和CSSOM树结合起来,使DOM树的节点拥有CSS样式,得到带有样式的DOM树)

C. 布局

        遍历以上得到的DOM树,得到layout树。(计算宽高,相对包含块的位置)

这里生成的layout树并不会和DOM树一一对应,例如display:none节点不会被加载到layout树中。

D. 分层

        举个例子:在三维空间中的z轴分层,例如z-index,但是实际并不一样。

        浏览器并不会每次都渲染整个页面,而是将页面分成多个层次,每次只渲染需要改变的层。每个分层都会占用一定的内存资源,所以浏览器并不能分太多的层。

(可以在CSS中使用will-change:transform属性生成一个新图层)

 E. 绘制

        这里会经过两个线程的处理。

        主线程 为每个图层单独产生绘制指令集合,描述这一层该如何画。

        

        蓝色为窗口,黑色为分块 。 

        完成绘制后将每个图层的绘制信息交给合成线程进行分块处理,合成线程将其分成更多的小区域,通过开启多个线程来分块工作。

F. 光栅化

        合成线程将块信息交给GPU,快速处理,得到一块一块的位图。

G. 画

        合成线程拿到每个图层的块位图后,生成指引信息,指引是标识每个位图会画到那个具体位置。合成线程会把指引提交给GPU,GPU使用显卡,渲染页面。



 

关于reflow:

reflow 的本质就是重新计算 layout 树。当进行了会影响布局树的操作后,需要重新计算布局树,会引发 layout。

当修改css或html时,就会触发修改CSSOM树和DOM树,然后修改布局树,也就是B,C,D,E,F,G步骤的重新执行。重新把页面画一遍。

为了避免连续的多次操作导致布局树反复计算,浏览器会合并这些操作,当 JS 代码全部完成后再进行统一计算。所以,改动属性造成的 reflow 是异步完成的。

因此在开发中,有时用JS并不能获取到最新的布局属性。


 

关于repaint:

repaint 的本质就是重新根据分层信息(也就是E步骤)计算了绘制指令。

通过绘制指令进行F,G

当页面被改动就会引起reflow,而reflow一定会引起repaint。


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热情且勇敢、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值