昨天 @hashseed 为 Node.js 提交了一个 issue:RFC: speeding up Node.js startup using V8 snapshot#17058
hashseed 是一名 Google 工程师,是 V8 开发者,同时也为 Node.js 贡献代码。在 issue 中 hashseed 写道:
我最近研究了 Node.js 的启动代码,我认为我们可以通过使用 V8 snapshot 让它启动的更快。我写了一个设计文档来解释几个要点。
设计文档:Speeding up Node.js startup using V8 snapshot(Google Doc 需*)
Node.js 核心的大多数代码都是使用 JavaScript 实现的。当应用启动时,Node.js 首先创建 V8::Isolate,其次是 V8::Context,接着才是 node::Environment。然后准备创建 process 对象,以及其它对象,然后运行 bootstrap_node.js 设置运行环境。只有执行完上述所有的任务后,Node.js 才开始运行用户脚本。
所有这一切都会造成启动性能的损失。有一个不严谨的比较:执行 d8 -e "" 代码,D8(V8 的开发版 shell)需要大约 50 毫秒, 而高端工作站的 Node.js,执行 node -e "" 却需要 400 毫秒。
V8 的启动快照(startup snapshot)是可以提升创建 V8 isolate 和 V8 contexts 的效率。它由两个部分组成:isolate 快照和 context 快照。
而 V8 启动快照 也不是什么新鲜玩意,早在 2015 年就已经被 V8 采用。相关博文:Custom startup snapshots(需*)。
简而言之,使用快照就不需要再从头开始建立 isolate,V8 可以简单地把之前序列化的 isolate 对象图进行反序列化就可以了。这同样适用于 context 快照。这样一来,V8 能够显著加快启动。
Node.js 也得益于创建一个新的 isolate 和新的 context。然而,启动过程中的后续步骤并不是快照的一部分,因此导致明显的开销。如果我们能创建 Node.js 已全面启动的快照,但此时还没有开始执行任何用户脚本,那么我们就可以减少启动时间。简单做一下评估,大概可以高达 8 倍。
hashseed 在 《Speeding up Node.js startup using V8 snapshot》简单描述了大概的实施细节,包括启动和执行相分离、原生绑定、创建快照的时机、等等…… hashseed 表示这是一个 side project,他将花费很长时间才能取得进展。
今年 4 月份,GitHub 已经使用了 V8 startup snapshot 技术来提升 Atom 的启动速度,Improving Startup Time
V8 还可以更快,Node.js 还可以更快,JavaScript 还可以更快,…… 拭目以待吧
公众号回复 V8
可查看我的 V8 专题。