简述浏览器渲染机制

作者: 泡杯感冒灵 | 来源:发表于2018-09-01 13:32 被阅读0次

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

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

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

    1. DOM:Document Object Model,浏览器将HTML解析成树形的数据结构,简称DOM。
    2. CSSOM:CSS Object Model,浏览器将CSS解析成树形的数据结构,简称CSSOM。
    3. Render Tree: DOM和CSSOM合并后生成Render Tree,如下图:


      image.png
    4. Layout: 计算出Render Tree每个节点的具体位置。
    5. Painting:通过显卡,将Layout后的节点内容分别呈现到屏幕上。

    三 : 需要注意的是:

    • 当我们浏览器获得HTML文件后,会自上而下的加载,并在加载过程中进行解析和渲染。
    • 加载说的就是获取资源文件的过程,如果在加载过程中遇到外部CSS文件和图片,浏览器会另外发送一个请求,去获取CSS文件和相应的图片,这个请求是异步的,并不会影响HTML文件的加载。
    • 但是如果遇到Javascript文件,HTML文件会挂起渲染的进程,等待JavaScript文件加载完毕后,再继续进行渲染。
      为什么HTML需要等待JavaScript呢?因为JavaScript可能会修改DOM,导致后续HTML资源白白加载,所以HTML必须等待JavaScript文件加载完毕后,再继续渲染,这也就是为什么JavaScript文件在写在底部body标签前的原因。

    四 : 浏览器渲染的整个流程

    image.png

    浏览器整个流程如上图所示:

    1. 当用户输入一个URL时,浏览器就会向服务器发出一个请求,请求URL对应的资源
    2. 接受到服务器的响应内容后,浏览器的HTML解析器,会将HTML文件解析成一棵DOM树,DOM树的构建是一个深度遍历的过程,当前节点的所有子节点都构建完成以后,才会去构建当前节点的下一个兄弟节点。
    3. 将CSS解析成CSSOM树(CSS Rule Tree)
    4. 根据DOM树和CSSOM树,来构建Render Tree(渲染树),注意渲染树,并不等于DOM树,因为一些像head或display:none的东西,就没有必要放在渲染树中了。
    5. 有了Render Tree,浏览器已经能知道网页中有哪些节点,各个节点的CSS定义,以及它们的从属关系,下一步操作就是Layout,顾名思义,就是计算出每个节点在屏幕中的位置。
    6. Layout后,浏览器已经知道哪些节点要显示,每个节点的CSS属性是什么,每个节点在屏幕中的位置是哪里,就进入了最后一步painting,按照算出来的规则,通过显卡,把内容画到屏幕上。

    这里还要说两个概念,一个是Reflow,另一个是Repaint。这两个不是一回事。

    • Repaint ——改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸没有变。
    • Reflow ——元件的几何尺寸变了,我们需要重新验证并计算Render Tree。是Render Tree的一部分或全部发生了变化。
    • reflow 几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显 示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲 染。通常我们都无法预估浏览器到底会 reflow 哪一部分的代码,它们都彼此相互影响着。
      注:display:none会触发reflow,而visibility:hidden只会触发repaint,因为没有发现位置变化。

    五 : DOM和CSSOM的具体构建流程:

    DOM 和 CSSOM 都是以" Bytes → characters → tokens → nodes → object model. " 这样的方式生成最终的数据。如下图所示:


    image.png

    具体到DOM树的构建,如下图:


    image.png
    1、 当服务器返回一个HTML文件给浏览器的时候,浏览器接受到的是一些字节数据。

    2、 然后浏览器根据HTTP响应中的编码方式(通过是UTF8),解析字节数据,得到一些字符。如果这个时候编码方式跟文件的字节编码不一致,便会出现乱码。所以我们通过使用<meta http-equiv="content-type"content="text/html;charset=utf-8">来告诉浏览器我们页面使用的是什么编码。

    3、 这个时候,浏览器再根据DTD中的对元素(标签)的定义,对这些接受到的字符进行语义化(token)。我们经常在html文件的第一行,定义<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">,这个DTD就是告诉浏览器,那些字符是有意义的,那些字符是无意义的。DTD常见的有严格、过渡、框架和HTML5三种。不同的DTD中,有不同的元素定义。比如过渡的DTD中就比严格的DTD中多出了<center>、<font>等等一些元素的定义,也就是说使用严格的DTD,即使你在你的HTML文件中使用了<center>,浏览器也会忽略掉的。所以也就有了一些人使用不同的DTD或者不使用DTD的时候,布局会明显不同的原因了。

    4、 接着,浏览器再使用这些语义块(token)创建对象,形成一个个节点了。

    5、 然后HTML解析器就会从HTML文件的头部到尾部,一个个地遍历这些节点。当这些节点是普通节点的话,HTML解析器就会将这些节点加入到DOM树中。当这些节点是JS代码的话,HTML解析器就会将控制权交给JS解析器。如果这些节点是CSS代码的话,HTML解析器就会将控制权交给CSS解析器。不过,当外联的JS代码和CSS代码还没从服务器传到浏览器的时候,这个时候如果DOM树上有可视元素的话,浏览器通常会选择在这个时候,将一些内容提前渲染到屏幕上来。

    6、 当HTML解析器读到最后一个节点的时候,整个DOM树也构建完成了,这个时候就会触发domContentloaded事件。而很多JS库(像JQ)通常会在这个时候有所反应的。

    至此,DOM树就全部构建完成了。

    相关文章

      网友评论

        本文标题:简述浏览器渲染机制

        本文链接:https://www.haomeiwen.com/subject/yngywftx.html