对浏览器渲染过程的理解

一 : 为什么要了解浏览器渲染页面的机制,主要还是性能的优化。

1.了解浏览器如何进行加载,我们可以在引用外部样式文件,外部JS时,将它们放到合适的位置,是浏览器以最快的速度,将文件加载完毕。
2.了解浏览器如何进行解析,我们可以在构建DOM结构,组织CSS选择器的时候,选择最优的写法,提高浏览器的解析速率。
3.了解浏览器如何进行渲染,明白渲染的过程,我们在设置元素属性,编写JS文件时,可以减少“重绘”,“重新布局”的消耗。

二 : 要了解清楚渲染机制,要先弄明白几个基本概念

DOM Tree:浏览器将HTML解析成树形的数据结构。DOM 和 CSSOM 都是以" Bytes → characters → tokens → nodes → object model. " 这样的方式生成最终的数据。如下图所示

  • DOM树在构建的过程中可能会被CSS和JS的加载而执行阻塞。(这在后面会详细介绍。)

  • display:none 的元素也会在DOM树中。

  • 注释也会在DOM树中

  • script标签会在DOM树中

在这里插入图片描述
CSSOM:CSSOM是一组允许JavaScript操作CSS的API。它非常类似于DOM,但是用于CSS而不是HTML。它允许用户动态读取和修改CSS样式。

CSS Rule Tree:浏览器将CSS解析成树形的数据结构。

  • CSS解析可以与DOM解析同进行。

  • CSS解析与script的执行互斥 。

  • 在Webkit内核中进行了script执行优化,只有在JS访问CSS时才会发生互斥。

Render Tree(渲染树)(webkit): DOM和CSSOM合并后生成Render Tree。
  在这里插入图片描述
  
Frame tree(帧树)(gecko):Gecko 里把格式化好的可视元素称做“帧树”

layout(布局)(webkit): 有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系,从而去计算出每个节点在屏幕中的位置。

reflow(回流)(gecko):当浏览器发现某个部分发生了点变化影响了布局,需要倒回去重新渲染,内行称这个回退的过程叫 reflow。reflow 会从 这个 root frame 开始递归往下,依次计算所有的结点几何尺寸和位置。reflow 几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显 示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲 染。通常我们都无法预估浏览器到底会 reflow 哪一部分的代码,它们都彼此相互影响着。
 
painting(绘制): 按照算出来的规则,通过显卡,把内容画到屏幕上。
  
repaint(重绘):改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸没有变。

注意:(1)display:none 的节点不会被加入Render Tree,而visibility: hidden 则会,

  • display : 隐藏对应的元素但不挤占该元素原来的空间。
  • visibility: 隐藏对应的元素并且挤占该元素原来的空间

所以,如果某个节点最开始是不显示的,设为display:none是更优的。

(2)display:none 会触发 reflow,而 visibility:hidden 只会触发 repaint,因为没有发现位置变化。

(3)有些情况下,比如修改了元素的样式,浏览器并不会立刻reflow 或 repaint 一次,而是会把这样的操作积攒一批,然后做一次 reflow,这又叫异步 reflow 或增量异步 reflow。但是在有些情况下,比如resize 窗口,改变了页面默认的字体等。对于这些操作,浏览器会马上进行 reflow。
   
三: 浏览器渲染的主要流程
1.webkit渲染的主要流程
在这里插入图片描述
2.gecko渲染的主要流程
在这里插入图片描述
尽管Webkit与Gecko使用略微不同的术语,这个过程还是基本相同的,如下:
1.浏览器将html解析成一个dom树。dom树的构建过程是一个深度遍历的过程,即当前节点的所有子节点都构建好后才会去构建当前节点的兄弟节点。
2.将css解析成css规则树
3.dom树和css规则树来构造render tree(渲染树)。有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系。注意:Rendering Tree 渲染树并不等同于 DOM 树,因为一些像Header或display:none的东西就没必要放在渲染树中了。
4. 下一步是layout(布局),计算出每个节点在屏幕中的位置。
5. 再下一步就是绘制,即遍历render树,通过显卡,把内容画到屏幕上。
注意:上述这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的html都解析完成之后再去构建和布局render树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容。

四:对dom树构建的再次说明
在这里插入图片描述
1、 当服务器返回一个HTML文件给浏览器的时候,浏览器接受到的是一些字节数据。
2、 然后浏览器根据HTTP响应中的编码方式(通过是UTF8),解析字节数据,得到一些字符。如果这个时候编码方式跟文件的字节编码不一致,便会出现乱码。所以我们通过使用<meta http-equiv="content-type"content=“text/html;charset=utf-8”>来告诉浏览器我们页面使用的是什么编码。
3、 这个时候,浏览器再根据DTD(文档类型定义)中的对元素(标签)的定义,对这些接受到的字符进行语义化(token)。我们经常在html文件的第一行,定义DOCTYPE ,这个DTD就是告诉浏览器,那些字符是有意义的,那些字符是无意义的。DTD常见的有严格、过渡、框架和HTML5三种。不同的DTD中,有不同的元素定义。
4、接着,浏览器再使用这些语义块(token)创建对象,形成一个个节点了。
5、 然后HTML解析器就会从HTML文件的头部到尾部,一个个地遍历这些节点。当这些节点是普通节点的话,HTML解析器就会将这些节点加入到DOM树中。当这些节点是JS代码的话,HTML解析器就会将控制权交给JS解析器。如果这些节点是CSS代码的话,HTML解析器就会将控制权交给CSS解析器。不过,当外联的JS代码和CSS代码还没从服务器传到浏览器的时候,这个时候如果DOM树上有可视元素的话,浏览器通常会选择在这个时候,将一些内容提前渲染到屏幕上来。
6、 当HTML解析器读到最后一个节点的时候,整个DOM树也构建完成了,这个时候就会触发domContentloaded事件。而很多JS库(像JQ)通常会在这个时候有所反应的。
至此,DOM树就全部构建完成了

五:阻塞渲染
还不是很理解,理解会另开一篇详细记录。

六:几条关于优化渲染效率的建议
结合上文和我看到的一些文章,有以下几点可以优化渲染效率

合法地去书写 HTML 和 CSS ,且不要忘了文档编码类型。

样式文件应当在 head 标签中,而脚本文件在 body 结束前,这样可以防止阻塞的方式。

简化并优化CSS选择器,尽量将嵌套层减少到最小。

尽量减少在 JavaScript 中进行DOM操作。

修改元素样式时,更改其class属性是性能最高的方法。

尽量用 transform 来做形变和位移。

转载内容来源:
作者:holdtom
链接:https://www.imooc.com/article/40004
来源:慕课网

作者:holdtom
链接:https://www.imooc.com/article/40004
来源:慕课网

作者:泡杯感冒灵
链接:https://www.jianshu.com/p/05eb1b17b298
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

https://www.cnblogs.com/slly/p/6640761.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值