メインコンテンツまでスキップ

カスタムスタートアップスナップショット

· 約4分
Yang Guo ([@hashseed](https://twitter.com/hashseed)), ソフトウェアエンジニアおよびエンジンプリヒーターの提供者

JavaScript仕様には多くの組み込み機能が含まれています。例えば、数学関数から完全装備の正規表現エンジンまでです。V8の新しいコンテキストにはこれらの関数が最初から利用可能です。これが機能するためには、グローバルオブジェクト(例えばブラウザのwindowオブジェクト)とすべての組み込み機能が設定され、コンテキストが作成される際にV8のヒープに初期化されなければなりません。この初期化を一から行うにはかなりの時間がかかります。

幸いなことに、V8はこれを効率化するためのショートカットを使用しています。ちょうど冷凍ピザを解凍して素早く夕食を準備するように、事前に準備されたスナップショットをヒープに直接デシリアライズして初期化済みのコンテキストを取得します。通常のデスクトップコンピュータでは、40msかかるコンテキスト作成時間を2ms未満に短縮できます。一般的な携帯電話では、この時間差は270msから10msになります。

Chrome以外のアプリケーションでV8を組み込む場合、通常のJavaScript以上のものが要求されることがあります。多くの場合、アプリケーションが実際に実行される前に、スタートアップ時に追加のライブラリスクリプトをロードします。例えば、V8をベースにしたシンプルなTypeScript VMは、TypeScriptソースコードをリアルタイムでJavaScriptに変換するためにスタートアップ時にTypeScriptコンパイラをロードする必要があります。

2ヶ月前にリリースされたV8 v4.3以降、組み込み者はスナップショットを利用して、初期化によるスタートアップ時間を短縮できます。この機能のテストケースにより、このAPIの動作が示されています。

スナップショットを作成するには、null終端文字列として埋め込む予定のスクリプトをv8::V8::CreateSnapshotDataBlobで呼び出します。新しいコンテキストを作成した後、このスクリプトはコンパイルされ実行されます。我々の例では、JavaScriptにすでに組み込まれているものに加えて関数を定義する2つのカスタムスタートアップスナップショットを作成します。

次にv8::Isolate::CreateParamsを使用して、新しく作成されたアイソレートをカスタムスタートアップスナップショットからコンテキストを初期化するように構成できます。そのアイソレートで作成されたコンテキストは、スナップショットを取得したコンテキストの正確なコピーです。スナップショットで定義された関数は、再び定義することなく利用できます。

これには重要な制約があります。スナップショットはV8のヒープのみをキャプチャできます。スナップショットを作成する際、V8が外部と相互作用することは禁止されています。このような相互作用には以下が含まれます:

  • APIコールバックの定義と呼び出し(例: v8::FunctionTemplateを使用して作成された関数)
  • 型付き配列の作成、バックアップストアがV8外部で割り当てられている可能性があるため

もちろん、Math.randomまたはDate.nowなどのソースから生成された値は、スナップショットがキャプチャされた後に固定されます。それらはもはや完全にランダムではなく、現在の時間も反映しません。

制約を除けば、スタートアップスナップショットは初期化時間を節約する素晴らしい方法です。我々の上記の例では、TypeScriptコンパイラのロードに費やすスタートアップから通常のデスクトップコンピュータで100msを削減できます。カスタムスナップショットをどのように活用するかを見るのを楽しみにしています!