来自:https://blog.csdn.net/qq243541844/article/details/51922947
【浏览器渲染原理】 渲染树和页面渲染
- 我们主要讨论以下列出的几个问题:
- 什么是渲染树?和DOM树及CSSOM树有什么关系?
- 渲染树是如何形成的?
- 浏览器渲染顺序问题
1.什么是渲染树?和DOM树及CSSOM树有什么关系?
首先我们得先了解一下渲染的基本步骤
当用户请求的资源通过浏览器网络层到达渲染引擎后。渲染工作就会开始。
第一步:浏览器解析HTML文档和解析CSS样式表形成DOM树和CSSOM树
第二步 : 结合DOM树和CSSDOM树形成 render树。 也就是我们所说的渲染树。渲染树
第三步: 浏览器在render树内对每个render节点进行布局处理,计算出每一个元素的大小和位置。确定其在屏幕上的位置
第四步:绘制。通过遍历render树将实际的像素显示到屏幕上
以上的步骤是一个渐进的步骤,但是为了提高用户体验,浏览器并不会等待所有html文档加载完成之后才建立渲染树并渲染。 他会在从网络层获取html文档的同时把已经接收到的局部内容先渲染出来
2.渲染树是如何形成的?
基于DOM树的一些可视化的节点,WebKit根据需要来创建相应的RenderObject节点,这些节点也构成了一颗树,称为render树。
Render树是基于Dom树建立起来的新的一棵树,Render节点和Dom节点并不是一一对应。所以什么情况下需要建立新的render节点呢?
- DOM树document节点
- DOM树种的可视化节点
- 某些情况下建立匿名的render节点
有一个问题就是什么算可视化节点呢?
比如 Html,Body,Div,P等就是可视化结点, 而非可视化节点就是 Head, Meta, Script等。
比如一个DIV的display属性是none,那么它就是非可视节点。
但是注意. 如果DIV的visibility属性是hidden,它是可视节点。
这是一个细节需要注意。
什么情况下建立匿名的render节点?
RenderBlock用来是用来表示块级元素, 为了处理上的方便,某些情况下需要建立匿名的RenderBlock对象,因为RenderBlock的子女必须都是内嵌的元素或者都是非内嵌的元素。所以,当它包含两种元素的时候,那么它会为相邻的内嵌元素创建一个块级RenderBlock节点,然后设置该节点为自己的子女并且设置这些内嵌元素为它的子女。
浏览器的渲染顺序问题(摘抄)
1.浏览器加载和渲染html的顺序
1、IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的。
2、在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都已经下载完)
3、如果遇到语义解释性的标签嵌入文件(JS脚本,CSS样式),那么此时IE的下载过程会启用单独连接进行下载。
4、并且在下载后进行解析,解析过程中,停止页面所有往下元素的下载。阻塞加载
5、样式表在下载完成后,将和以前下载的所有样式表一起进行解析,解析完成后,将对此前所有元素(含以前已经渲染的)重新进行渲染。
6、JS、CSS中如有重定义,后定义函数将覆盖前定义函数
2. JS的加载
2.1 不能并行下载和解析(阻塞下载)
2.2 当引用了JS的时候,浏览器发送1个js request就会一直等待该request的返回。因为浏览器需要1个稳定的DOM树结构,而JS中很有可能有代码直接改变了DOM树结构,比如使用 document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修改DOM树,需要重新构建DOM树的情况,所以 就会阻塞其他的下载和呈现.