【浏览器】渲染原理探究

1,364 阅读5分钟

前言

做为前端,打交道最多的就是浏览器了,也是我们必须熟悉的。所以接下来我们讲一下浏览器的渲染原理。

如果对浏览器的工作原理了解清楚,可以为web性能优化提供方向以及理论依据。

先上很多人都见过的一幅图:

浏览器渲染机制

浏览器的主要功能

浏览器的主要功能就是向服务器发出请求,在浏览器窗口中展示您选择的网络资源。这里所说的资源一般是指 HTML 文档,也可以是 PDF、图片或其他的类型。资源的位置由用户使用 URI(统一资源标示符)指定。

浏览器解释并显示 HTML 文件的方式是在 HTML 和 CSS 规范中指定的。这些规范由网络标准化组织 W3C(万维网联盟)进行维护。多年以来,各浏览器都没有完全遵从这些规范,同时还在开发自己独有的扩展程序,这给网络开发人员带来了严重的兼容性问题。如今,大多数的浏览器都是或多或少地遵从规范。

浏览器的主要构成

  • 用户界面(User Interface) - 包括地址栏、后退/前进按钮、书签目录等,也就是你所看到的除了用来显示你所请求页面的主窗口之外的其他部分。
  • 浏览器引擎(Browser Engine) - 用来查询及操作渲染引擎的接口。
  • 渲染引擎(Rendering Engine) - 用来显示请求的内容,例如,如果请求内容为html,它负责解析html及css,并将解析后的结果显示出来。
  • 网络(Networking) - 用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作。
  • JS解释器(JS Interpreter) - 用来解释执行JS代码。
  • UI后端(UI Backend) - 用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口。
  • 数据存储(DB Persistence) - 属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,HTML5定义了web database技术,这是一种轻量级完整的客户端存储技术。

浏览器的渲染过程

1. HTML解析,构建DOM

浏览器解析HTML,构建DOM树。 解析HTML到构建出DOM当然过程可以简述如下:

Bytes → characters → tokens → nodes → DOM

其中比较关键的几个步骤:

1. Conversion转换:浏览器将获得的HTML内容(Bytes)基于他的编码转换为单个字符
2. Tokenizing分词:浏览器按照HTML规范标准将这些字符转换为不同的标记token。每个token都有自己独特的含义以及规则集
3. Lexing词法分析:分词的结果是得到一堆的token,此时把他们转换为节点对象,这些对象分别定义他们的属性和规则 
4. DOM构建:因为HTML标记定义的就是不同标签之间的关系,这个关系就像是一个树形结构一样
例如:body对象的父节点就是HTML对象,然后段落p对象的父节点就是body对象

事实上,构建DOM的过程中,不是等所有Token都转换完成后再去生成节点对象,而是一边生成Token一边消耗Token来生成节点对象。换句话说,每个Token被生成后,会立刻消耗这个Token创建出节点对象。注意:带有结束标签标识的Token不会创建节点对象。

还有两点需要特别注意的地方。第一,DOM 树解析的过程是一个深度优先遍历,即先构建当前节点的所有子节点,再构建下一个兄弟节点。第二,若遇到 JavaScript 标签,则 DOM 树的构建会暂停,直至脚本执行完毕。

2. 解析CSS,生成CSS规则树

同理,CSS规则树的生成也是类似。

Bytes → characters → tokens → nodes → CSSOM

在这一过程中,浏览器会确定下每一个节点的样式到底是什么,并且这一过程其实是很消耗资源的。因为样式你可以自行设置给某个节点,也可以通过继承获得。在这一过程中,浏览器得递归 CSSOM 树,然后确定具体的元素到底是什么样式。

同时,解析 CSS 规则树时 js 执行将暂停,直至 CSS 规则树就绪。

注意:CSS匹配HTML元素是一个相当复杂和有性能问题的事情。所以,DOM树要小,CSS尽量用id和class,千万不要过渡层叠下去。

3. 合并DOM树和CSS规则,生成render树

当我们生成 DOM 树和 CSSOM 树以后,就需要将这两棵树组合为渲染树。 一般来说,渲染树和DOM树是相对应的,但不是严格意义上的一一对应,因为有一些不可见的DOM元素不会插入到渲染树中,如head这种不可见的标签或者display: none等。

4. 布局render树(Layout/reflow),负责各元素尺寸、位置的计算

布局:通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸。 Layout:也称为Reflow,即回流。一般意味着元素的内容、结构、位置或尺寸发生了变化,需要重新计算样式和渲染树。

5. 绘制render树(paint),绘制页面像素信息

绘制阶段:系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。 Repaint:即重绘。意味着元素发生的改变只是影响了元素的一些外观之类的时候(例如,背景色,边框颜色,文字颜色等),此时只需要应用新样式绘制这个元素就可以了。

后记: 小伙伴们,如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果觉得本文还不错,记得点个赞哦! 本文首发地址为: Vae's Blog