浏览器渲染原理及流程

  咱们可能都知道浏览器含有一个渲染引擎,用来渲染窗口所展现的内容。默认状况下,渲染引擎能够显示html、xml文档及图片,它也能够借助插件(一种浏览器扩展)显示其余类型数据,例如使用PDF阅读器插件,用于显示PDF格式。可是其具体的渲染原理和流程估计也有不少人都不知道或者不清楚吧。这些天研究了一下浏览器的渲染原理,有了些心得,在这里跟你们分享一下,这里只讨论渲染引擎最主要的用途——显示应用了CSS以后的html及图片。html

 

渲染引擎简介web

  本文所讨论的浏览器——Firefox、Chrome和Safari是基于两种渲染引擎构建的,Firefox使用Geoko——Mozilla自主研发的渲染引擎,Safari和Chrome都使用webkit。后端

 

渲染主流程浏览器

  渲染引擎首先经过网络得到所请求文档的内容,一般以8K分块的方式完成。下面是渲染引擎在取得内容以后的基本流程:网络

  解析html以构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树数据结构

 

 

 

  这里先解释一下几个概念,方便你们理解:dom

  DOM Tree:浏览器将HTML解析成树形的数据结构。异步

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

  Render Tree: DOM和CSSOM合并后生成Render Tree。字体

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

  painting: 按照算出来的规则,经过显卡,把内容画到屏幕上。

  reflow(回流):当浏览器发现某个部分发生了点变化影响了布局,须要倒回去从新渲染,内行称这个回退的过程叫 reflow。reflow 会从 <html> 这个 root frame 开始递归往下,依次计算全部的结点几何尺寸和位置。reflow 几乎是没法避免的。如今界面上流行的一些效果,好比树状目录的折叠、展开(实质上是元素的显 示与隐藏)等,都将引发浏览器的 reflow。鼠标滑过、点击……只要这些行为引发了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引发它内部、周围甚至整个页面的从新渲 染。一般咱们都没法预估浏览器到底会 reflow 哪一部分的代码,它们都彼此相互影响着。

  repaint(重绘):改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,可是元素的几何尺寸没有变。

注意:(1)display:none 的节点不会被加入Render Tree,而visibility: hidden 则会,因此,若是某个节点最开始是不显示的,设为display:none是更优的。

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

   (3)有些状况下,好比修改了元素的样式,浏览器并不会马上reflow 或 repaint 一次,而是会把这样的操做积攒一批,而后作一次 reflow,这又叫异步 reflow 或增量异步 reflow。可是在有些状况下,好比resize 窗口,改变了页面默认的字体等。对于这些操做,浏览器会立刻进行 reflow。

 

  来看看webkit的主要流程:

 

  再来看看Geoko的主要流程:

 


  Gecko 里把格式化好的可视元素称作“帧树”(Frame tree)。每一个元素就是一个帧(frame)。 webkit 则使用”渲染树”这个术语,渲染树由”渲染对象”组成。webkit 里使用”layout”表示元素的布局,Gecko则称为”reflow”。Webkit使用”Attachment”来链接DOM节点与可视化信息以构建渲染树。一个非语义上的小差异是Gecko在HTML与DOM树之间有一个附加的层 ,称做”content sink”,是建立DOM对象的工厂。

  尽管Webkit与Gecko使用略微不一样的术语,这个过程仍是基本相同的,以下:

  1. 浏览器会将HTML解析成一个DOM树,DOM 树的构建过程是一个深度遍历过程:当前节点的全部子节点都构建好后才会去构建当前节点的下一个兄弟节点。

  2. 将CSS解析成 CSS Rule Tree 。

  3. 根据DOM树和CSSOM来构造 Rendering Tree。注意:Rendering Tree 渲染树并不等同于 DOM 树,由于一些像Header或display:none的东西就不必放在渲染树中了。

  4. 有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系。下一步操做称之为layout,顾名思义就是计算出每一个节点在屏幕中的位置。

  5. 再下一步就是绘制,即遍历render树,并使用UI后端层绘制每一个节点。

  注意:上述这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽量早的将内容呈现到屏幕上,并不会等到全部的html都解析完成以后再去构建和布局render树。它是解析完一部份内容就显示一部份内容,同时,可能还在经过网络下载其他内容