探索全球最热门的 JavaScript 引擎:QuickJS 只是其中之一!

发表时间: 2023-04-02 07:14

家好,很高兴又见面了,我是"高级前端‬进阶‬",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

高级前端‬进阶

今天给大家带来的主题是“全网10+最优秀的JavaScript引擎”,一部分是拿来即用的开源JavaScript引擎、另一部分是浏览器本身内置的JavaScript引擎介绍。话不多说,直接开始!

jerryscript

JerryScript 是一个轻量级的 JavaScript 引擎,用于资源受限的设备,例如:微控制器。 它可以在 RAM 小于 64 KB 和闪存 ROM 小于 200 KB 的设备上运行。

JerryScript 的主要特征:

  • 完全符合 ECMAScript 5.1 标准
  • 为 ARM Thumb-2 编译时为 160K 二进制大小
  • 针对低内存消耗进行了大量优化
  • 用 C99 编写以实现最大的可移植性
  • 快照支持将 JavaScript 源代码预编译为字节码
  • 成熟的C API,易于嵌入应用

JerryScript是物联网场景的首选JavaScript 引擎,其支持设备上的编译、执行,并提供从 JavaScript 访问外围设备的功能。

目前JerryScript在Github上有超过6.5k的star、660+的fork、超过100+的代码贡献者,是一个值得长期关注的项目。

Duktape

Duktape 是一个可嵌入的 Javascript 引擎,专注于可移植性和紧凑性(Compact Footprint)。Duktape 很容易集成到 C/C++ 项目中:将 duktape.c、duktape.h 和 duk_config.h 添加到构建中,并使用 Duktape API 从 C 代码调用 ECMAScript 函数,反之亦然。

Duktape的主要特点包括:

  • 可嵌入、便携、紧凑
  • ECMAScript E5/E5.1 兼容,从 ES2015+ 更新了一些语义
  • 部分支持 ECMAScript 2015 (E6) 和 ECMAScript 2016 (E7)、Post-ES5 功能状态、kangax/compat-table
  • ES2015 TypedArray 和 Node.js 缓冲区绑定
  • WHATWG 编码 API 生活标准
  • 内置调试器、正则表达式引擎、Unicode 支持、协程等自定义功能
  • 最小的平台依赖性、结合引用计数和带终结的标记清除垃圾收集
  • 使用 ECMAScript ES2015 代理对象子集的属性虚拟化(Property virtualization
  • 用于缓存编译函数的字节码转储/加载
  • 包括分发时可选的日志记录框架、基于 CommonJS 的模块加载器、CBOR绑定等
  • 基于MIT 自由许可证开源

目前Duktape在Github上有超过5.5k的star、510+的fork、超过60+的代码贡献者,是一个值得长期关注的项目。

MuJS

MuJS 是一个轻量级Javascript 解释器,设计用于嵌入其他软件中以扩展它们的脚本功能。

MuJS 的设计重点是体积、正确性和简单性。 它是用可移植的 C 语言编写的,并按照 ECMA-262 的规定实现了 ECMAScript。 与本地代码绑定的接口被设计为尽可能简单易用,与 Lua 非常相似,无需与byzantine C++ 模板机制交互,或担心标记和取消标记垃圾收集根,或与晦涩的构建系统。

MuJS 由 Artifex Software 开发和维护。 它最初是为与 MuPDF 查看器一起使用而开发的,但被设计为作为一个独立的组件使用。目前,MuJS 是在 ISC 许可证下分发的免费开源软件。

目前MuJS在Github上有超过0.7k的star、80+的fork、超过12+的代码贡献者,是一个值得长期关注的项目。

QuickJS

FFmpeg 和 QEMU 的创建者 Fabrice Bellard 以及 C 语言专家 Charlie Gordon 在 2019 年宣布开源 QuickJS , QuickJS 在 MIT 许可下发布,是一个“小而完整的JavaScript引擎”。

图片来自:https://flutterawesome.com/a-quickjs-engine-for-flutter/

在性能方面,QuickJS 明显优于其他可选方案。例如:在 bench-v8 测试中,QuickJS 领先 DukTape 一倍多,领先 JerryScript 三倍,领先 MuJS 七倍。

除了性能优势外,QuickJS 还有以下特点:

  • 小巧且易于嵌入:只有几个 C 文件,没有外部依赖。一个简单的 hello world 程序编译为 x86 后只有 210 KB
  • 解释器启动时间极短:在台式 PC 的单核上运行 ECMAScript 测试套件的 75000 个测试大约需要 100 秒,运行时实例的完整生命周期在不到 300 微秒内就可以完成。
  • 支持完整的 ES2020,包括模块、异步生成器和完整的 Annex B 支持(旧版 Web 兼容性)。
  • 选择 ES2020 特性时,几乎 100% 通过了 ECMAScript Test Suite 测试。
  • 可没有外部依赖的情况下将 Javascript 源代码编译为可执行文件
  • 使用引用计数(以减少内存使用并具有确定性行为)和循环删除的垃圾收集模式。
  • 支持数学扩展:BigDecimal、BigFloat、运算符重载、bigint 模式、数学模式。
  • 在 Javascript 中实现上下文着色命令行解释器、带有 C 库包装器的小型内置标准库。

关于QuickJS的更多内容可以继续阅读我的另一篇文章:

  • 《什么原因让我坚决选择 QuickJS ?》

目前 QuickJS 在Github上有超过5.8k的star、600+的fork、超过100+的代码贡献者。

Espruino

Espruino 是一个微处理器的 JavaScript 解释器,基于它创建了首个 JavaScript 微处理器 Espruino Board。Espruino 在国外知名的众筹平台KickStarter上发布之后才被人知晓,其发明人是来自英国的Gordon Williams。

Espruino是一种运行在微控制器上的软件,实现了Javascript解释器的功能,因此你只要会用Javascript,就可以对微控制器进行编程,释放自己的创意,DIY出自己的电子作品。

Espruino开发板是一个小电脑,任何人都可以利用它去控制身边的东西,由JavaScript解释器实时反馈,因此不强依赖开发经验。只要把Espruino开发板插到电脑上,使用Chrome Web IDE或喜欢的终端应用程序,就可以马上编写程序。

Espruino的事件驱动特性使它非常省电,低至0.1mA的功耗,即使使用普通的5号电池也能运行好几年,如果用上一个小的太阳能电池,那就可以永久使用了。

目前Espruino的软件和硬件都是开源的。目前 Espruino 在Github上有超过2.6k的star、710+的fork、超过110+的代码贡献者。

V7

V7 是用 C 编写的最小的 JavaScript 引擎,用于 C/C++ 的嵌入式 JavaScript 引擎。

V7 的显著特点如下:

  • 跨平台:适用于任何平台,从 Arduino 到 MS Windows
  • 文件小尺寸: 编译的静态文件大小在 40k - 120k 范围内,初始化时的 RAM 占用空间约为 800 字节,有冻结功能,不过 15k 没有冻结功能
  • 简单直观的 C/C++ API:很容易将现有的C/C++函数导出到JavaScript环境中
  • 标准:V7 实现 JavaScript 5.1
  • 开箱即用:V7 提供一个带有硬件(SPI、UART 等)、文件、加密、网络 API 的辅助库
  • 源代码符合 ISO C 和 ISO C++
  • 非常容易集成:只需将两个文件:v7.h 和 v7.c 复制到开发项目中

V7 使得使用 JavaScript 对物联网 (IoT) 嵌入式设备进行编程成为可能,是完整堆栈 Mongoose OS 平台的一部分。不过需要注意的是:V7项目目前已弃用,取而代之的是下面的mJS.

目前Espruino的软件和硬件都是开源的。目前 Espruino 在Github上有超过2.6k的star、710+的fork、超过110+的代码贡献者。

mJS

mJS 专为资源有限的微控制器而设计。 主要设计目标是:占用空间小和简单的 C/C++ 互操作性, mJS 实现了 ES6(JavaScript 版本 6)的严格子集:

  • 任何有效的 mJS 代码都是有效的 ES6 代码。
  • 任何有效的 ES6 代码不一定是有效的 mJS 代码。

在 32 位 ARM 上,mJS 引擎需要大约 50k 的闪存和不到 1k 的 RAM。 mJS 是 MongooseOS 的一部分,它支持为物联网设备编写脚本。

mJS有一些明显的局限性,比如:

  • 没有标准库。 没有字符串、数字、正则表达式、日期、函数等。
  • 没有闭包,只有词法作用域(即允许嵌套函数)。
  • 没有new操作, 要创建具有自定义原型的对象,请使用可用的 Object.create()。
  • 仅限严格模式,没有 var,只有 let。
  • 没有 for..of、=>、析构函数、生成器、Proxy、Promise。
  • 没有 == 或 !=,只有 === 和 !==。

更多限制性可以参考文末参考资料,这里不做过多列举。目前 mJS 在Github上有超过1.7k的star、160+的fork、超过10+的代码贡献者。

quickjs-emscripten

quickjs-emscripten 是QuickJS 的 Javascript/Typescript 绑定,一种现代 Javascript 解释器,编译为 WebAssembly。quickjs-emscripten具有以下明显特点:

  • 安全执行不受信任的 Javascript(最高 ES2020)。
  • 在 QuickJS 运行时内创建和操作值。
  • 将宿主函数暴露给 QuickJS 运行时。
  • 使用 asyncify 执行使用异步函数的同步代码。
import { getQuickJS } from "quickjs-emscripten"async function main() {  const QuickJS = await getQuickJS()  const vm = QuickJS.newContext()  const world = vm.newString("world")  vm.setProp(vm.global, "NAME", world)  world.dispose()  const result = vm.evalCode(`"Hello " + NAME + "!"`)  if (result.error) {    console.log("Execution failed:", vm.dump(result.error))    result.error.dispose()  } else {    console.log("Success:", vm.dump(result.value))    result.value.dispose()  }  vm.dispose()}main()

除了quickjs-emscripten 外,还有wasm-jseval、wasmedge-quickjs、tiny-js、JScript .NET 、Tamarin、GNU Guile、Nashorn 、iv 、CL-JavaScript 、BESEN 、Hermes 、Graal.js 、Continuum 、Futhark、InScript 、JScript 、Jint 、Narcissus 、QtScript等特定场景的JavaScript引擎实现,这里不再进一步展开,可以在参考资料中找到它们的相关介绍。

目前 quickjs-emscripten 在Github上有超过0.8k的star、65+的fork、超过10+的代码贡献者,使用的项目数130+。

浏览器内置引擎

V8

V8是Google开源的 JavaScript 和 WebAssembly 引擎,用C++编写,它用于 Chrome 和 Node.js 等场景。支持 Windows7或更高版本、macOS10.12+ 以及使用x64、IA-32 或ARM处理器的Linux 系统上运行。其他系统(IBM i、AIX)和处理器(MIPS、ppcle64、s390x)由外部维护。

V8可以独立运行,也可以嵌入到任何C++应用程序中。

SpiderMonkey

SpiderMonkey 是 Firefox 和 Mozilla 的 Javascript 引擎,现在SpiderMonkey可以被单独编译,即可以在自己的应用程序中使用它,下载地址是:
http://ftp.mozilla.org/pub/mozilla.org/js/
。SpiderMonkey 是用 C 实现,还有一个叫做 Rhino的 Java版本。

SpiderMonkey 的源代码可以在多种平台上进行编译。在 Windows 平台下,按照下载文件中的 readme 文件中的提示,会编译出一个 Dll,然后可以在应用程序中使用这个 Dll。

JavaScriptCore (JSC)

JavaScriptCore (JSC) 是 Safari、Mail、App Store 和 MacOS 中许多其他应用程序使用的 JavaScript 引擎。 JSC 引擎负责执行每一行 JavaScript (JS),比如浏览到新网站或发送/接收电子邮件时。

如今前端最火的运行时Bun(旨在替代 Node.js,其是用 Zig 编写的)就是由 JavaScriptCore 提供支持,从而大大减少了启动时间和内存使用量。目前,Bun也号称是前端最快的JS运行时。

Chakra

Chakra 是微软 2008 年新创建的一个JavaScript 引擎,其基本构建原则是要具备现代Web 应用所需要的性能特性,并能非常容易地应用于各种不断出现的场景。也就是说,Chakra 需要能够快速启动和运行,提供卓越的用户体验,并充分发挥底层硬件的潜能。

除 Microsoft Edge 浏览器之外,Chakra 还应用于通用 Windows 应用、 Azure DocumentDB 、 Cortana 、 Outlook.com 及 TypeScript (做过专门优化)。微软还使 Node.js 可以使用 Windows 10 上的 Chakra ,从而使开发人员可以在新 IoT 平台 Windows 10 IoT Core 上使用 Node.js。

carakan

2019 年由 Opera Software ASA 开发的 JavaScript 引擎,包含在 Opera 网络浏览器的 V10.50 版本中,直到随着 Opera 15(2013 年发布)切换到 V8。

本文总结

本文主要和大家介绍全网最火的 10+ JavaScript引擎,一部分是拿来即用的开源JavaScript引擎、另一部分是浏览器本身内置的JavaScript引擎,同时对每一个引擎的特点、使用场景做了一个简单的介绍。

因为篇幅有限,文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏!


参考资料

https://github.com/jerryscript-project/jerryscript

https://github.com/bellard/quickjs

https://github.com/svaarala/duktape

https://github.com/espruino/Espruino

https://github.com/cesanta/v7

https://github.com/cesanta/mjs

https://github.com/justjake/quickjs-emscripten

https://github.com/v8/v8

https://github.com/mozilla-spidermonkey

https://zhuanlan.zhihu.com/p/55479666?utm_id=0

https://www.infoq.cn/article/2015/12/javascript-chakra

https://github.com/gfwilliams/tiny-js

https://wohugb.gitbooks.io/javascript/content/bom/engine.html

https://www.infoworld.com/article/2675942/opera-working-on-faster-javascript-engine.html

https://en.wikipedia.org/wiki/List_of_ECMAScript_engines

图片版权:来自Mihir Verma的文章《Inside Javascript Engine》,文章链接:
https://dev.to/mihirverma7781/inside-javascript-engine-373