🚀⚙️深入探究 JavaScript 引擎 - (Chrome V8)
网络浏览器是互联网世界的重要组成部分。每当我们在地址栏中输入 URL 时,它都会从远程服务器获取资源,并将其显示在屏幕上。在此期间,它主要经历三个过程
- 拿来
- 过程
- 展示
首先,它通过互联网从后续的网络服务器获取数据。
然后Render engine
, 会处理接收到的资源。之后,Browser Engine
会进行数据呈现。
那么这一切是怎么发生的呢……?
为了更好地理解这些过程,我们应该知道浏览器如何处理 JavaScript。这是由 JavaScript 引擎完成的。
JavaScript引擎是一个执行 JavaScript 代码的程序或解释器。JS 是一种高级动态语言,它无法直接与机器的低级逻辑交互。因此,JavaScript 引擎可以实现为标准解释器,或即时编译器,将 JavaScript 编译为某种形式的字节码。请参见下图中 JS 引擎的高级概述。
- 解析器: HTML 解析器将获取所有通过
<script>
标签加载的脚本。脚本中的源代码将以 UTF-16 字节流的形式加载到字节流解码器中。然后,字节流解码器将字节解码为 token,并将其发送到解析器。 -
AST(抽象语法树)
解析器根据获取到的 token 创建节点,并利用这些节点构建抽象语法树 (AST)。 -
解释器
解释器遍历抽象语法树 (AST) 并生成字节码。它逐行读取代码。生成字节码后,AST 会被删除以清理内存空间。 -
分析器
分析器监视并观察代码以对其进行优化。 -
编译器
编译器提前工作并创建已编写代码的翻译,然后编译为机器可以读取的低级语言。
我们已经了解了 JS 引擎的不同组件。现在让我们来看看有哪些不同的JavaScript 引擎可用。
- V8 — 开源,由 Google 开发,用 C++ 编写
- Rhino — 由 Mozilla 基金会管理,开源,完全用 Java 开发
- Spider Monkey——第一个 JavaScript 引擎,它曾为 Netscape Navigator 提供支持,如今则为 Firefox 提供支持
- JavaScriptCore — 开源,以 Nitro 为市场推广,由 Apple 为 Safari 开发
- KJS — KDE 引擎,最初由 Harri Porten 为 KDE 项目的 Konqueror 网络浏览器开发
- Chakra (JScript9) — Internet Explorer
- Chakra Core(JavaScript)——Microsoft Edge(现在使用 v8)
- Nashorn,作为 OpenJDK 的一部分开源,由 Oracle Java 语言和工具组编写
- JerryScript——是一款轻量级的物联网引擎。
V8
谷歌开发的 V8 引擎是开源的,用 C++ 编写。谷歌 Chrome 浏览器内部就使用了这款引擎。V8 也用于流行的 Node.js 和 Deno。为了获得高性能,V8 引擎将 JavaScript 代码转换为更高效的机器码,而不是使用解释器。虽然大多数现代 JavaScript 引擎都采用了类似的方法,但 V8 的独特之处在于它不产生任何中间代码。
V8 的工作原理
V8 通过实现 JIT(即时)编译器,在执行时将 JavaScript 代码编译为机器码。JIT 编译器兼具传统编译器和解释器的优点,并将它们融合在一起。
当 V8 编译 JavaScript 代码时,解析器会生成 AST(抽象语法树)。语法树是 JavaScript 代码语法结构的树形表示。解释器 Ignition 根据这棵语法树生成字节码。优化编译器 TurboFan 最终获取字节码并将其生成优化的机器码。
让我们进一步了解一下 V8 性能Ignition
解释器和编译器背后的 2 个主要管道Turbofan
点火
V8 中的解释器称为 Ignition。解释器生成字节码。这对于只需运行一次的代码非常有用。字节码在 JavaScript 引擎内部运行。解释代码更容易运行,但速度稍慢。Ignition 通过实现三个目标来解决内存开销问题。
- 减少内存使用量
- 减少启动时间
- 降低复杂性
涡轮风扇
TurboFan 流水线遵循一些步骤将字节码转换为机器码。流水线中的优化是根据 Ignition 收集的反馈进行的。
TurboFan 的在线 JIT 风格编译和优化完成了 V8 从源代码到机器码的翻译。
有时,我们可能会遇到重复的代码块。JavaScript 编译器会进行反馈,并收集正在执行代码的分析数据。如果遇到每次调用都使用相同类型参数且被调用多次的函数,则该代码会经过 TurboFan 的优化。TurboFan 会针对热点代码生成高度优化的机器级代码,这些代码会直接在 CPU 上运行。只有当 JS 引擎检测到某个代码是热点代码时,TurboFan 才会启动。如果某个代码运行频率较高、在循环中运行等,则该代码就是热点代码。编译后的代码可以直接在 CPU 上运行,速度会更快。
文章来源:https://dev.to/edisonpappi/how-javascript-engines-chrome-v8-works-50if