Web前端之路前端开发那些事让前端飞

浏览器渲染原理与过程

2018-06-01  本文已影响118人  Srtian

原文地址:http://srtian96.gitee.io/blog/2018/06/01/%E6%B5%8F%E8%A7%88%E5%99%A8%E6%B8%B2%E6%9F%93%E5%8E%9F%E7%90%86/

一、浏览器如何渲染网页

要了解浏览器渲染页面的过程,首先得知道一个名词——关键路径渲染。关键渲染路径(Critical Rendering Path)是指与当前用户操作有关的内容。例如用户在浏览器中打开一个页面,其中页面所显示的东西就是当前用户操作相关的内容,也就是浏览器从服务器那收到的HTML,CSS,JavaScript等相关资源,然后经过一系列处理后渲染出来的web页面。

而浏览器渲染的过程主要包括以下五步:

具体如下图过程如下图所示:

Webkit

需要注意的是,以上五个步骤并不一定一次性顺序完成,比如DOM或CSSOM被修改时,亦或是哪个过程会重复执行,这样才能计算出哪些像素需要在屏幕上进行重新渲染。而在实际情况中,JavaScript和CSS的某些操作往往会多次修改DOM或者CSSOM。

下面我们就来详细的了解一下这几个过程及需要注意的事项。

二、浏览器渲染网页的具体流程

2.1 构建DOM树

当浏览器客户端从服务器那接受到HTML文档后,就会遍历文档节点然后生成DOM树,DOM树结构和HTML标签一一对应。需要注意记下几点:

  1. DOM树在构建的过程中可能会被CSS和JS的加载而执行阻塞。(这在后面会详细介绍。)
  2. display:none 的元素也会在DOM树中。
  3. 注释也会在DOM树中
  4. script标签会在DOM树中

2.2 CSS解析

浏览器会解析CSS文件并生成CSS规则树,在过程中,每个CSS文件都会被分析成StyleSheet对象,每个对象都包括CSS规则,CSS规则对象包括对应的选择器和声明对象以及其他对象。
在这个过程需要注意的是:

2.3 构建渲染树(Rendr tree construction)

通过DOM树和CSS规则树,浏览器就可以通过它两构建渲染树了。浏览器会先从DOM树的根节点开始遍历每个可见节点,让后对每个可见节点找到适配的CSS样式规则并应用。具体的规则有以下几点需要注意:

2.4 渲染树布局(layout of the render tree)

布局阶段会从渲染树的更节点开始遍历,由于渲染树的每个节点都是一个Render Object对象,包含宽高,位置,背景色等样式信息。所以浏览器就可以通过这些样式信息来确定每个节点对象在页面上的确切大小和位置,布局阶段的输出就是我们常说的盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小。需要注意的是:

2.5 渲染树绘制(Painting the render tree)

在绘制阶段,浏览器会遍历渲染树,调用渲染器的paint()方法在屏幕上显示其内容。渲染树的绘制工作是由浏览器的UI后端组件完成的。

三、浏览器渲染网页的那些事儿

3.1 阻塞渲染

前面我们有提到这方面的问题,说到资源的阻塞我们清楚的是,现代浏览器总是并行加载自语言。例如当HTML解析器被脚本阻塞时,解析器虽然会停止构建DOM,但仍然会辨识该脚本后面的资源,并进行预加载。且由于以下两点。浏览器会延迟 JavaScript 的执行和 DOM 构建:

正是由于以上这些原因,script标签的位置很重要我们在实际开发中应该尽量坚持以下两个原则:

3.2 回流和重绘(reflow和repaint)

我们都知道HTML默认是流式布局的,但CSS和JS会打破这种布局,改变DOM的外观样式以及大小和位置。因此我们就需要知道两个概念:

需要注意的是,display:none 会触发 reflow,而visibility: hidden属性则并不算是不可见属性,它的语义是隐藏元素,但元素仍然占据着布局空间,它会被渲染成一个空框,这在我们上面有提到过。所以visibility:hidden 只会触发 repaint,因为没有发生位置变化。

我们不能避免reflow,但还是能通过一些操作来减少回流:

  1. 用transform做形变和位移.
  2. 通过绝对位移来脱离当前层叠上下文,形成新的Render Layer。

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

3.3 几条关于优化渲染效率的建议

结合上文和我看到的一些文章,有以下几点可以优化渲染效率

  1. 合法地去书写 HTML 和 CSS ,且不要忘了文档编码类型。
  2. 样式文件应当在 head 标签中,而脚本文件在 body 结束前,这样可以防止阻塞的方式。
  3. 简化并优化CSS选择器,尽量将嵌套层减少到最小。
  4. 尽量减少在 JavaScript 中进行DOM操作。
  5. 修改元素样式时,更改其class属性是性能最高的方法。
  6. 尽量用 transform 来做形变和位移

参考文章:

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

https://zhuanlan.zhihu.com/p/29418126

https://juejin.im/post/5a8e242c5188257a6b060000

上一篇下一篇

猜你喜欢

热点阅读