浏览器渲染原理及流程

46次阅读

共计 1765 个字符,预计需要花费 5 分钟才能阅读完成。

渲染引擎简介

目前常用的浏览器:
Firefox . chrome . safari 是基于两种渲染引擎构建的,Firefox 使用 Geoko, 是 Mozilla 自主研发的渲染引擎,Safari 和 Chrome 都使用 webkit.

渲染主流程

概念解释
DOM Tree: 浏览器将 HTML 解析成树形的数据结构.
CSS Rule Tree: 浏览器将 CSS 解析在树形的数据结构.
Render Tree:DOM 和 CSSOM(CSS Object Model:CSS 对象模型) 合并后生成 Render Tree.
layout: 有了 Render Tree,浏览器已经能知道网页中有哪些节点,各个节点的 CSS 的定义以及他们的从属关系,从而去计算出每个节点的屏幕中的位置.
painting: 按照算出来的规则,通过显卡,把内容画到屏幕上.
reflow(回流): 当浏览器发现某个部分发生了点变化影响了布局,需要倒回去重新渲染,称此为回退的过程,叫 reflow.reflow 会从 <html> 这个 root frame 开始递归往下,依次计算所有的结点几何尺寸和位置。feflow 几乎是无法避免的.
例如:树状目录的折叠,展开,实质上是元素的显示与隐藏等,都将引起浏览器的 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

主流程
渲染引擎首先通过网络获得所请求文档的内容,通常以 8K 分块的方式完成。基本流程为:
解析 HTML 以构建 DOM 树 -> 解析 CSS 构建 CSSOM -> 将 DOM 树与 CSSOM 树合并,构建 Render 树 -> 布局 render 树 -> 绘制 render 树

来看看 webkit 的流程:

接下来是 Gecko 的流程:
Gecko 里把格式化好的可视元素称做“桢树”(Frame tree),每一个元素就是一个桢,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 来构造 Render Tree,Render tree 不等于 DOM Tree, 因为像 Header 或 display:none 的东西没有必要放在渲染树中.
4. 有了 Render Tree, 浏览器已经能知道网页中有哪些节点,各个节点的 CSS 定义以及他们的从属关系,下一步操作称之为 layout,顾名思义就是计算出每个节点在屏幕中的位置.
5. 下一步就是绘制,即遍历 render 树,并使用 UI 后端层绘制每个节点。
注意:上述这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的 html 都解析完成之后再去构建和布局 render 树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容.

正文完
 0

浏览器渲染原理及流程

46次阅读

共计 2395 个字符,预计需要花费 6 分钟才能阅读完成。

现代浏览器的组成
浏览器可以分为两部分:shell 和浏览器内核,shell 是外壳,如工具栏,菜单等,内核是根本,是基于标记语言显示的程序或模块。
浏览器内核分为两部分:渲染引擎和 JS 引擎。
渲染引擎
渲染引擎主要负责解析浏览器所呈现的内容,比如 HTML,CSS。渲染引擎的主要流程:
始解析 HTML 文档,并将各标记逐个转化成“内容树”上的 DOM 节点。同时也会解析外部 CSS 文件以及样式元素中的样式数据。HTML 中这些带有视觉指令的样式信息将用于创建另一个树结构:呈现树。
呈现树包含多个带有视觉属性(如颜色和尺寸)的矩形。这些矩形的排列顺序就是它们将在屏幕上显示的顺序。
呈现树构建完毕之后,进入“布局”处理阶段,也就是为每个节点分配一个应出现在屏幕上的确切坐标。下一个阶段是绘制 – 呈现引擎会遍历呈现树,由用户界面后端层将每个节点绘制出来。
需要着重指出的是,这是一个渐进的过程。为达到更好的用户体验,呈现引擎会力求尽快将内容显示在屏幕上。它不必等到整个 HTML 文档解析完毕之后,就会开始构建呈现树和设置布局。在不断接收和处理来自网络的其余内容的同时,呈现引擎会将部分内容解析并显示出来。Webkit 渲染引擎主流程如下图:
Gecko 渲染引擎如下图:
浏览器的结构
1、用户界面。包括地址栏、前进 / 后退按钮、书签菜单等。除了浏览器主窗口显示的您请求的页面外,其他显示的各个部分都属于用户界面。
2、浏览器引擎。在用户界面和呈现引擎之间传送指令。
3、呈现引擎。负责显示请求的内容。如果请求的内容是 HTML,它就负责解析 HTML 和 CSS 内容,并将解析后的内容显示在屏幕上。
4、用户界面后端。用于绘制基本的窗口小部件,比如组合框和窗口。其公开了与平台无关的通用接口,而在底层使用操作系统的用户界面方法。
5、JavaScript 解释器。用于解析和执行 JavaScript 代码。
6、数据存储。这是持久层。浏览器需要在硬盘上保存各种数据,例如 Cookie。新的 HTML 规范 (HTML5) 定义了“网络数据库”,这是一个完整(但是轻便)的浏览器内数据库。
7、网络。用于网络调用,比如 HTTP 请求。其接口与平台无关,并为所有平台提供底层实现。
关于 DOM 解析
有如下 HTML 片段
<html>
<head>
<title>Web page parsing</title>
</head>
<body>
<div>
<h1>Web page parsing</h1>
<p>This is an example Web page.</p>
</div>
</body>
</html>

关于 CSS 解析
<doc>
<title>A few quotes</title>
<para>
Franklin said that <quote>”A penny saved is a penny earned.”</quote>
</para>
<para>
FDR said <quote>”We have nothing to fear but <span>fear itself.</span>”</quote>
</para>
</doc>

CSS 样式如下:
/* rule 1 */ doc {display: block; text-indent: 1em;}

/* rule 2 */ title {display: block; font-size: 3em;}

/* rule 3 */ para {display: block;}

/* rule 4 */ [class=”emph”] {font-style: italic;}
解析成 CSS tree
注意:CSS 遍历 DOM,一层层找到对应的渲染规则是十分复杂的过程,这也是我们经常要求尽量精简 DOM 结构,减少 CSS 嵌套层级的原因。
CSS 渲染流程

1、计算 CSS 属性;2、构建 Render Tree;3、Layout,进行定位,元素的坐标及尺寸,将元素放到指定位置;4、绘制
注意:图中有两种箭头,一种是指向流程自身的,表示“回流”,即修改某个属性会导致页面进行重新渲染,一种的指向外部的,表示“重绘”,即修改某个属性不会影响整个页面布局。
重绘与回流
这是前端经常会提到的两个概念。重绘:Repaint,可以理解为页面局部某个元素要进行重新绘制,比如修改元素的背景颜色,但是几何尺寸并不会变;回流:Reflow,可以理解为页面整个重新绘制,比如修改元素的尺寸,往往会导致整个 render tree 要进行重新计算,reflow 是从 html 标签开始自上而下一次重新计算元素尺寸,重新布局。通过两者概念区别明显得知,回流要比重绘的成本大得多,我们应该尽量减少回流操作,减少页面性能消耗。
(1)引起回流的方法或操作:
任何会改变元素几何信息 (元素的位置和尺寸大小) 的操作,都会触发回流。

元素尺寸改变——边距、填充、边框、宽度和高度
内容变化,比如用户在 input 框中输入文字
浏览器窗口尺寸改变——resize 事件发生时
计算 offsetWidth 和 offsetHeight 属性
设置 style 属性的值

(2)常见引起重绘属性和方法

减少 reflow/repaint
1. 不要一条一条地修改 DOM 的样式。与其这样,还不如预先定义好 css 的 class,然后修改 DOM 的 className。

把 DOM 离线后修改。

使用 documentFragment 对象在内存里操作 DOM
先把 DOM 给 display:none(有一次 reflow),然后你想怎么改就怎么改。比如修改 100 次,然后再把他显示出来。clone 一个 DOM 结点到内存里,然后想怎么改就怎么改,改完后,和在线的那个的交换一下。

不要把 DOM 结点的属性值放在一个循环里当成循环里的变量。不然这会导致大量地读写这个结点的属性。

4. 尽可能的修改层级比较低的 DOM。当然,改变层级比较底的 DOM 有可能会造成大面积的 reflow,但是也可能影响范围很小。
5. 千万不要使用 table 布局。因为可能很小的一个小改动会造成整个 table 的重新布局。

正文完
 0