浏览器原理之“渲染原理”
浏览器渣染原理
html字符串->煊染->像素信息
面试题:浏览器是如何染页面的?
渣染流水线
1 | 当浏览器的网络线程收到HTML文档后,会产生一个染任务,并将其传递给染主线程的消息队列。 |
1解析
1 | 渣染的第一步是解析Html. |
解析遇到CSS怎么办
1 | 如果主线程解析到Link位置,此时外部的Css文件还没有下载解析好,主线程不会等待,继续解析后续的HTML。这是因为下载和解析CSS的工作是在预解析线程中进行的。这就是CSS不会阻塞HTML解析的根本原因。 |
解析遇到Script怎么办
1 | 如果主线程解析到script位置,会停止解析HTML,转而等待JS文件下载好,并将全局代码解析执行完成 |
这里渲染遇到JS是不行的,必须等待CSS下载完成过后,然后把代码放到主线程启动V8引擎去运行JS,运行后才能继续解析HTML
这样的原因是因为JS代码里边有可能会改动当前的DOM,他有可能会把这个解析出来的DOM改动了,DOM不是解析完才生成的,是一边解析一边生成
1 | 第一步完成后,会得到DOM树和CSS OM树,浏览器的默认样式、内部样式、外部样式、行内样式均会包含 |
2样式计算
到了这一步 就和 css属性值的计算过程 有关系了,样式计算就发生在这一步
CSS中有两块很重要的知识: 其一就是 《css属性值的计算过程》
1 | 包含 |
其二是 《视觉格式化模型》
1 | “盒模型” |
1 | 渣染的下一步是样式计算。 |
计算完后会得到一个最终样式 也就是 计算后的样式 叫 Computed Style
计算完后的就是最终样式 就是 就是它所有的CSS属性必须要全部有值
3布局
1 | 接下来是布局,布局完成后会得到布局树。 |
就是根据DOM树根据它的样式算出每个节点的尺寸和位置
页面上它们元素之间的位置和尺寸是相互影响的,一个元素的位置和尺寸变了,它可能会导致整个布局就产生变化
它的位置相对的是 包含块,
简单来说就是一个元素的活动区域
有些隐藏的元素是没有几何信息的,他不会生成在布局树里边
比方有一个元素,它涉及到为元素选择器 ::before 他设置了before过后 , 这个玩意儿在DOM树里边是不存在的 , 但是在布局数里边是存在的
b是个内容 有一句话 :
一些术语什么 行级元素,块级元素都是淘汰掉的,W3C官方都不用了,都是10多年前的,叫什么元素一般是HTML用的叫法,这是CSS阿所以叫 行盒,块盒
1 | 《内容必须在行盒中》,文本内容必须放到行盒里面, |
总之的意思就是有很多种情况会导致DOM树和layout就是布局数它不对应
布局对于JS而言虽然不能获取布局树里的对象,但是它可以间接的获取一些信息
4分层
下一步是分层
1 | 主线程会使用一套复杂的策略对整个布局树中进行分层。 |
跟堆叠上下文有关的属性就会影响到分层结果
5绘制
这里的绘制,是为每一层生成如何绘制的指令
1 | 再下一步是绘制 |
6分块
1 | 完成绘制后,主线程将每个图层的绘制信息提交给合成线程,剩余工作将由合成线程完成。 |
7光栅化
1 | 分块完成后,进入光栅化阶段。 |
光栅化是在GPU里面做的
8画
1 | 最后一个阶段就是画了 |
常见面试题:什么是reflow?
1 | reflow的本质就是重新计算layout树。 |
常见面试题:什么是是repaint?
repaint的本质就是重新根据分层信息计算了绘制指令。
当改动了可见样式后,就需要重新计算,会引发repaint。
由于元素的布局信息也属于可见样式,所以reflow一定会引起repaint。
常见面试题:为什么transform的效率高?
因为transform既不会影响布局也不会影响绘制指令,它影响的只是染流程的最后一个「draw』阶段
由于draw阶段在合成线程中,所以transform的变化几乎不会影响染主线程。反之,染主线程无论如何忙碌,也不会影响transform的变化。