Node.js 新計劃:使用 V8 snapshot 將啟動速度提升 8 倍

justjavac發表於2017-11-17

昨天 @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 專題:

justjavac微信公眾號
justjavac微信公眾號

相關文章