浏览器如何渲染页面

开启渲染

浏览器网络线程接收到html文档后,会生成一个渲染任务,并将其加入到渲染主线程的消息队列中,根据事件循环机制,渲染主线程从消息队列中取出任务,开启渲染流程。

渲染流程

渲染流程分为多个阶段:解析HTML,样式计算,layout,分层,绘制,分块,光栅化,draw。每个阶段都有明确的输入输出,上一个阶段的输出会成为下一阶段的输入。

解析HTML

为了提高解析效率,浏览器会开启一个预解析线程,提前下载HTML文件中的外部CSS和JS文件。

如果HTML解析过程中遇到link标签,主线程不会等待而是继续解析后面的HTML元素,因为CSS的解析与下载都在预解析线程中进行。

如果HTML解析过程中遇到script标签,主线程会停止解析HTML,转而等待JS下载完成,并将全局代码执行完成后,才会继续解析HTML,因为JS代码执行过程中可能修改当前的DOM树。

结果:DOM树和CSSOM树。

样式计算

主线程根据生成的DOM树,依次为树中每个节点计算它的最终样式,称为Computed Style。

在这一过程中许多预设值会变成绝对值,相对单位会变成绝对单位。

结果:带样式的DOM树。

layout

布局阶段会依次遍历DOM树的每一个节点,计算每个节点的几何信息。例如节点的宽高,相对包含块的位置。

大部分时候,DOM和layout树并非一一对应。
比如**display: none;**的元素没有几何信息,不会生成到布局树,伪元素节点拥有几何信息,会生成到布局树。(内容必须包含在行盒中,行盒和块盒不能相邻)

结果:layout树

分层

主线程采用一套复杂的策略对layout树进行分层。

分层的好处在于每一层之间互不影响,提高绘制效率。

滚动条、堆叠上下文、opacity、transform等样式多少都会影响分层结果,也可以通过will-change属性更大程度上影响分层结果。

绘制

主线程会为每一层产生一个单独的指令集,用来描述这一层应该如何绘制。

结果:图层绘制指令集

分块

完成绘制后,主线程将每个图层的绘制信息交给合成线程,剩下的工作由合成线程完成。

合成线程首先对每个图层进行分块,将其划分成更小的区域。
它将从线程池中拿取多个线程进行分块工作。

结果:图层分块信息

光栅化

合成线程将图层的分块信息提交给GPU进程,由GPU进程开启多个线程进行进行光栅化,优先处理靠近视口区域的块。

结果:块位图

draw

合成线程拿到每个图层,每个块的位图后,生成一个个quad信息。

quad会标识出每个位图对应的屏幕位置,考虑旋转、缩放等变形操作。(变形发生在合成线程,与渲染主线程无关,所以transform效率较高)

合成线程会把quad提交给GPU进程,由GPU进程产生系统调用,提交给GPU硬件,最终完成屏幕成像。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值