一分钟快速了解 V8 引擎的工作流程
前言
众所周知,JavaScript 是一门高级编程语言,我们所编写的 JavaScript 代码并不能直接被浏览器执行,而是需要经过 JavaScript 引擎 编译过后,才能被识别并运行。

如上图所示, JavaScript 引擎只是浏览器渲染引擎工作中的一部分,专门负责解析 JavaScript 代码。JavaScript 引擎有很多种,比如用于 Safari 的 Nitro 引擎、Edge 的 Chakra 引擎以及 Chrome 的 V8 引擎。 本文我们简单介绍下 Google 的开源引擎 V8,了解 V8 引擎是怎么处理 JavaScript 代码的。
V8 引擎介绍
V8 引擎是由 Google 开发的开源 JavaScript 引擎,用于 Google Chrome 及 Chromium 中。V8 引擎在真正执行之前将 JavaScript 代码编译成了机器代码,而非字节码或是解释执行它,以此提升性能。
V8 引擎工作流程

- 首先,渲染引擎(浏览器内核)将源码交给 V8 引擎,Stream 进行编码转换。
- 其次,Scanner/扫描器进行词法分析,这里会将一些声明语句解析成下一个阶段所需要的格式:tokens。
- 然后根据函数是否调用决定 Parser/解析 或 PreParser/预解析。
- 解析:
- 创建执行上下文
- 解析被使用的代码
- 生成 AST (抽象语法树)
- 构建具体 scopes 信息,变量引用、声明等
- 抛出所有语法错误
- 预解析:
- 跳过未被使用的代码
- 不生成 AST (抽象语法树) ,创建无变量引用和声明的 scopes
- 依据规范抛出特定错误
- 解析速度更快
- 解析:
- 解析之后,Ignition/解释器会将 AST (抽象语法树) 生成对应的字节码,并开始执行它们。
- 同时有另外一个线程监测代码的执行过程,收集合适的数据进行回调。
- TurboFan 则根据收集到的数据去优化字节码,让它们能够快速的执行。
- 一个最简单的例子是,如果在运行过程中,TurboFan 发现某个函数的参数无论如何都只会是 32bit 整数,而不会是其他任何类型,那么它就可以省略掉很多类型检查上的操作了,完全有可能让一些加法被优化为单纯的 add 指令,而不是其他更加复杂的函数;但如果运行中发现,在某一时刻,传入的参数类型发生了变化,那么就会去除这次的优化,令代码回到本来的状态。
- 另外,在开始执行 JavaScript 代码时,也会有一些堆栈准备:
- JavaScript 执行环境
- 执行环境栈(ECStack, execution context stack)
- 执行上下文
- VO(G),全局变量对象
总结
通过本文我们简单的了解了 V8 引擎的工作流程,如果您在文中发现了任何错误或者有歧义之处,非常欢迎您指正并提出建议,以便我能够不断改进和提升文章的质量。
我是荼锦,一个兴趣使然的开发者。 非常感谢您阅读本文,希望本文对您有所帮助!
转载自:https://juejin.cn/post/7229586461246226469