启动快照 API


稳定性: 1 - 实验

v8.startupSnapshot 接口可用于为自定义启动快照添加序列化和反序列化钩子。 目前启动快照只能从源代码构建到 Node.js 二进制文件中。

$ cd /path/to/node
$ ./configure --node-snapshot-main=entry.js
$ make node
# 此二进制文件包含 entry.js 的执行结果
$ out/Release/node

在上面的例子中,entry.js 可以使用来自 v8.startupSnapshot 接口的方法来指定如何在序列化过程中为快照中的自定义对象保存信息,以及如何在快照的反序列化过程中使用这些信息来同步这些对象。 例如,如果 entry.js 包含以下脚本:

'use strict';

const fs = require('node:fs');
const zlib = require('node:zlib');
const path = require('node:path');
const assert = require('node:assert');

const {
  isBuildingSnapshot,
  addSerializeCallback,
  addDeserializeCallback,
  setDeserializeMainFunction,
} = require('node:v8').startupSnapshot;

const filePath = path.resolve(__dirname, '../x1024.txt');
const storage = {};

assert(isBuildingSnapshot());

addSerializeCallback(({ filePath }) => {
  storage[filePath] = zlib.gzipSync(fs.readFileSync(filePath));
}, { filePath });

addDeserializeCallback(({ filePath }) => {
  storage[filePath] = zlib.gunzipSync(storage[filePath]);
}, { filePath });

setDeserializeMainFunction(({ filePath }) => {
  console.log(storage[filePath].toString());
}, { filePath });

生成的二进制文件将在启动期间简单地打印从快照反序列化的数据:

$ out/Release/node
# 打印 ./test/fixtures/x1024.txt 的内容

目前该 API 仅适用于从默认快照启动的 Node.js 实例,即从用户端快照反序列化的应用程序无法再次使用这些 API。

Stability: 1 - Experimental

The v8.startupSnapshot interface can be used to add serialization and deserialization hooks for custom startup snapshots. Currently the startup snapshots can only be built into the Node.js binary from source.

$ cd /path/to/node
$ ./configure --node-snapshot-main=entry.js
$ make node
# This binary contains the result of the execution of entry.js
$ out/Release/node

In the example above, entry.js can use methods from the v8.startupSnapshot interface to specify how to save information for custom objects in the snapshot during serialization and how the information can be used to synchronize these objects during deserialization of the snapshot. For example, if the entry.js contains the following script:

'use strict';

const fs = require('node:fs');
const zlib = require('node:zlib');
const path = require('node:path');
const assert = require('node:assert');

const {
  isBuildingSnapshot,
  addSerializeCallback,
  addDeserializeCallback,
  setDeserializeMainFunction,
} = require('node:v8').startupSnapshot;

const filePath = path.resolve(__dirname, '../x1024.txt');
const storage = {};

assert(isBuildingSnapshot());

addSerializeCallback(({ filePath }) => {
  storage[filePath] = zlib.gzipSync(fs.readFileSync(filePath));
}, { filePath });

addDeserializeCallback(({ filePath }) => {
  storage[filePath] = zlib.gunzipSync(storage[filePath]);
}, { filePath });

setDeserializeMainFunction(({ filePath }) => {
  console.log(storage[filePath].toString());
}, { filePath });

The resulted binary will simply print the data deserialized from the snapshot during start up:

$ out/Release/node
# Prints content of ./test/fixtures/x1024.txt

Currently the API is only available to a Node.js instance launched from the default snapshot, that is, the application deserialized from a user-land snapshot cannot use these APIs again.