2021-12-10 js中的v8 引擎

编译型语言和解释性语言

```解释性语言:解释行语言,支持动态类型,弱类型,在程序运行的时候才进行编译,而编译前需要确定变量的类型,效率比较低,对不同系统平台有较大的兼容性

## 渲染引擎及网页渲染

为用户提供网页浏览服务无疑是最重要的功能,如下介绍:

### 渲染引擎

*   `渲染引擎` - 能够能够将HTML/CSS/JavaScript文本及相应的`资源文件`转换成`图像`结果.

*   `作用` - 将`资源文件`转化为`用户可见`的结果。

*   渲染引擎的种类 - `Tridend`(IE)、`Gecko(FF)`,`WebKit`(Safari,Chrome,Andriod浏览器)等.

*   `介绍` - `WebKit`是由苹果2005年发起的一个开源项目,引起了众多公司的重视,几年间被很多公司所采用,在移动端更占据了垄断地位。更有甚者,开发出了基于WebKit的支持HTML5的web操作系统(如:Chrome OS、Web OS)。

网页渲染过程:
image.png

过程 - 首先是网页内容,输入到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树的创建

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引擎

image.png

avaScript本质上是一种解释型语言,与编译型语言不同的是它需要一遍执行一边解析,而编译型语言在执行时已经完成编译,可直接执行,有更快的执行速度(如上图所示)。JavaScript代码是在浏览器端解析和执行的,如果需要时间太长,会影响用户体验。那么提高JavaScript的解析速度就是当务之急。JavaScript引擎和渲染引擎的关系如下图所示:

VAKBnJ.png

JavaScript语言是解释型语言,为了提高性能引入Java虚拟机C++编译器中的众多技术。现在JavaScript引擎的执行过程大致是:

源代码-→抽象语法树-→字节码-→JIT-→本地代码(V8引擎没有中间字节码)。一段代码的抽象语法树示例如下:

function demo(name) {
    console.log(name);
}

抽象语法树如下:

VAKTAI.png

V8更加直接的将抽象语法树通过JIT技术转换成本地代码,放弃了在字节码阶段可以进行的一些性能优化,但保证了执行速度。在V8生成本地代码后,也会通过Profiler采集一些信息,来优化本地代码。虽然,少了生成字节码这一阶段的性能优化,但极大减少了转换时间。

但是在2017年4月底,v8 的 5.9 版本发布了,新增了一个 Ignition 字节码解释器,将默认启动,从此之后将与JSCore有大致相同的流程。做出这一改变的原因为:(主要动机)减轻机器码占用的内存空间,即牺牲时间换空间;提高代码的启动速度;对 v8 的代码进行重构,降低 v8 的代码复杂度(V8 Ignition:JS 引擎与字节码的不解之缘 - CNode技术社区)。

你可能感兴趣的:(2021-12-10 js中的v8 引擎)