引子:2008年,Google公司以苹果开源项目WebKit作为内核,创建了一个新的项目Chromium,该项目的目标是创建一个快速的、支持众多操作系统的浏览器,包括
对桌面操作系统和移动操作系统的支持。WebKit是Chromium浏览器的内核,而Chrome浏览器一般选择Chromium的稳定版本作为它的基础,Chrome加入了一些私有的
编码解码器以支持音视频等,以及整合了Google众多的网络服务。
以下是WebKit和Chromium的关系,那么渲染引擎(浏览器内核)和WebKit是什么关系?
构建对象模型
浏览器渲染页面前先要构建DOM和CSSOM树,但这个构建过程不会去渲染
- 字节 → 字符 → 令牌 → 节点 → 对象模型。
- HTML 标记转换成文档对象模型 (DOM);CSS 标记转换成 CSS 对象模型 (CSSOM)。
- DOM 和 CSSOM 是独立的数据结构。
- Chrome DevTools Timeline 让我们可以捕获和检查 DOM 和 CSSOM 的构建和处理开销
浏览器每次处理 HTML 标记时,都会完成以上所有步骤:将字节转换成字符,确定令牌,将令牌转换成dom节点,然后构建 DOM 树。这整个流程可能需要一些时间才能完成,有大量 HTML 需要处理时更是如此。
在浏览器构建我们这个简单页面的 DOM 时,在文档的 head 部分遇到了一个 link 标记,该标记引用一个外部 CSS 样式表:style.css。由于预见到需要利用该资源来渲染页面,它会立即发出对该资源的请求,如果不另外声明,会是阻塞后面渲染的资源请求
CSSOM 为何具有树结构?为页面上的任何对象计算最后一组样式时,浏览器都会先从适用于该节点的最通用规则开始(例如,如果该节点是 body 元素的子项,则应用所有 body 样式),然后通过应用更具体的规则(即规则“向下级联”)以递归方式优化计算的样式。不过要记得浏览器有自己的默认样式,因此一开始以此为基础建立cssom树,我们平时用reset来覆盖和重新计算样式。
CSSOM和DOM是独立的数据结构,浏览器将两者关联在一起生成渲染树
渲染引擎及网页渲染
为用户提供网页浏览服务无疑是最重要的功能,如下介绍:
渲染引擎
渲染引擎
- 能够能够将HTML/CSS/JavaScript文本及相应的资源文件
转换成图像
结果.作用
- 将资源文件
转化为用户可见
的结果。- 渲染引擎的种类 -
Tridend
(IE)、Gecko(FF)
,WebKit
(Safari,Chrome,Andriod浏览器)等. 介绍
-WebKit
是由苹果2005年发起的一个开源项目,引起了众多公司的重视,几年间被很多公司所采用,在移动端更占据了垄断地位。更有甚者,开发出了基于WebKit的支持HTML5的web操作系统(如:Chrome OS、Web OS)。
WebKit
的大致结构
介绍:
图中的实线框,虚线框代表什么:
实线框
- 模块是所有移植的共有部分
。虚线框
- 不同的厂商可以自己实现
。
操作系统
- 是管理
和控制计算机硬件
与软件资源
的计算机程序
,是直接运行在“裸机”上的最基本的系统软件
,任何其他软件都必须在操作系统的支持下才能运行
。WebKit也是在操作系统上工作的
。第三方库
- 为了WebKit提供支持,如图形库、网络库、视频库等。WebCore
- 是各个浏览器使用的共享部分
,包括HTML解析器、CSS解析器、DOM和SVG等。JavaScriptCore
- 是WebKit的默认引擎
,在谷歌系列产品中被替换为V8引擎。WebKit Ports
- 是WebKit中的非共享部分
,由于平台差异
、第三方库
和需求的不同
等原因,不同的移植导致了WebKit不同版本
行为不一致,它是不同浏览器性能和功能差异的关键部分。
WebKit嵌入式编程接口 -
供浏览器调用\`,与移植密切相关,不同的移植有不同的接口规范。- 测试用例,包括布局测试用例和性能测试用例,用来验证渲染结果的正确性。
网页渲染流程
上面介绍了渲染引擎的各个模块,那么一张网页,要经历怎样的过程,才能展示给用户。
过程
- 首先是网页内容,输入到HTML解析器,HTML解析器解析,然后构建DOM树,在这期间如果遇到JavaScript代码则交给JavaScript引擎处理;如果来自CSS解析器的样式信息,构建一个内部绘图模型。该模型由布局模块计算模型内部各个元素的位置和大小信息,最后由绘图模块完成从该模型到图像的绘制。在网页渲染的过程中,大致可分为下面3个阶段:
1.
从输入URL到生成DOM树
- 1.1 地址栏
输入URL
,WebKit调用资源
加载器加载相应资源; - 1.2 加载器依赖网络模块建立连接,发送请求并接收答复;
- 1.3 WebKit接收各种网页或者资源数据,其中某些资源可能同步或异步获取;
- 1.4 网页
交给HTML解析器
转变为词语
; - 1.5 解释器根据
词语
构建节点,形成DOM树; - 1.6 如果节点是
JavaScript代码
,调用JavaScript引擎解释并执行
; - 1.7 JavaScript代码可能会修改DOM树结构;
- 1.8 如果节点依赖其他资源,如图片\css、视频等,调用资源加载器加载它们,但这些是异步加载的,不会阻碍当前DOM树继续创建;如果是JavaScript资源URL(没有标记异步方式),则需要停止当前DOM树创建,直到JavaScript加载并被JavaScript引擎执行后才继续DOM树的创建
- 1.1 地址栏
2.
从DOM树到构建WebKit绘图上下文
- 2.1 CSS文件被CSS解释器解释成内部表示;
- 2.2 CSS解释器完成工作后,在DOM树上附加样式信息,生成RenderObject树;
- 2.3 RenderObject节点在创建的同时,WebKit会根据网页层次结构构建RenderLayer树,同时构建一个
虚拟绘图上下文
。
3.
绘图上下文到最终图像呈现
- 3.1 绘图上下文是一个与平台无关的抽象类,它将每个绘图操作桥接到不同的具体实现类,也就是绘图具体实现类;
- 3.2 绘图实现类也可能有简单的实现,也可能有复杂的实现,软件渲染、硬件渲染、合成渲染等;
- 3.3 绘图实现类将2D图形库或者3D图形库绘制结果保存,交给浏览器界面进行展示。
上述是一个完整的渲染过程,现代网页很多都是动态的,随着网页与用户的交互,浏览器需要不断的重复渲染过程。
JavaScript引擎
JavaScript本质上是一种解释型语言
,与编译型语言不同的是它需要一遍执行一边解析
,而编译型语言在执行时已经完成编译,可直接执行,有更快的执行速度(如上图所示)。JavaScript代码是在浏览器端解析和执行的,如果需要时间太长,会影响用户体验。那么提高JavaScript的解析速度就是当务之急
。JavaScript引擎和渲染引擎的关系如下图所示:
JavaScript语言是解释型语言,为了提高性能
,引入
了Java虚拟机
和C++编译器
中的众多技术。现在JavaScript引擎的执行过程大致是:
源代码
-→抽象语法树
-→字节码
-→JIT
-→本地代码
(V8引擎没有中间字节码)。一段代码的抽象语法树示例如下:
function demo(name) {
console.log(name);
}
抽象语法树
如下:
V8更加直接的将抽象语法树通过JIT技术转换成本地代码,放弃了在字节码阶段可以进行的一些性能优化,但保证了执行速度。在V8生成本地代码后,也会通过Profiler采集一些信息,来优化本地代码。虽然,少了生成字节码这一阶段的性能优化,但极大减少了转换时间。
但是在2017年4月底,v8 的 5.9 版本发布了,新增了一个 Ignition 字节码解释器,将默认启动,从此之后将与JSCore有大致相同的流程。做出这一改变的原因为:(主要动机)减轻机器码占用的内存空间,即牺牲时间换空间;提高代码的启动速度;对 v8 的代码进行重构,降低 v8 的代码复杂度(V8 Ignition:JS 引擎与字节码的不解之缘 - CNode技术社区)。
JavaScript的性能和C相比还有不小的距离,可预见的未来估计也只能接近它,而不是与它相比,这从语言类型上已经决定。下面将对V8引擎进行更为细致的介绍。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。