Files
node/lib/worker_threads.js
Shelley Vohr e38eede0e5 lib: load fewer builtins when bootstrapping without a snapshot
Contexts that are not deserialized from the built-in snapshot -- worker
threads, and the main context of embedders that create their own
isolate or of `node --no-node-snapshot` -- compile (with the code cache
at best) every builtin the bootstrap touches, so each eagerly required
builtin is startup time (~0.15-0.4 ms apiece). A number of them are only
required eagerly so that they end up in the snapshot, or for features
the bootstrap path never uses.

Load lazily what those paths do not need:

- is_main_thread.js: preload util, url, the ESM loader (translators,
  resolver, module_job/map, source maps, node:module, vm modules, mime,
  data_url, the TypeScript stripper), internal/blob and
  internal/dns/utils only while building a snapshot; they load on first
  use otherwise.
- fs: internal/blob (+ internal/encoding and its tables) is only used
  by fs.openAsBlob().
- internal/url: internal/data_url (+ internal/mime) is only used by the
  Buffer-returning file URL helpers.
- internal/process/execution, the CommonJS loader, esm/translators and
  esm/load: the TypeScript stripper and data: URL helpers are only
  needed for TypeScript sources / data: URLs.
- pre_execution: internal/dns/utils (+ internal/net) is only needed up
  front to validate an explicit --dns-result-order or to register the
  resolver's snapshot serializer; the default order becomes the
  variable's initializer.
- internal/worker: event_loop_utilization and error_serdes are only
  needed once a sub-worker's ELU is read or it reports an error.
- worker_threads: `locks` is defined lazily, like util's lazy exports.

Main-thread startup with the snapshot is unchanged (the same modules
are preloaded into it; the bootstrap-modules test lists are adjusted).
A bare worker compiles 95 -> 83 builtins (cold start -5%); without the
snapshot an empty CommonJS entry point compiles 76 -> 59 builtins and an
empty ES module entry point 76 -> 69.

Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65329
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Aviv Keller <me@aviv.sh>
2026-08-22 17:07:39 +00:00

64 lines
1.1 KiB
JavaScript

'use strict';
const { defineLazyProperties } = require('internal/util');
const {
isInternalThread,
isMainThread,
SHARE_ENV,
resourceLimits,
setEnvironmentData,
getEnvironmentData,
threadId,
threadName,
Worker,
} = require('internal/worker');
const {
MessagePort,
MessageChannel,
markAsUncloneable,
moveMessagePortToContext,
receiveMessageOnPort,
BroadcastChannel,
} = require('internal/worker/io');
const {
postMessageToThread,
} = require('internal/worker/messaging');
const {
markAsUntransferable,
isMarkedAsUntransferable,
} = require('internal/buffer');
module.exports = {
isInternalThread,
isMainThread,
MessagePort,
MessageChannel,
markAsUncloneable,
markAsUntransferable,
isMarkedAsUntransferable,
moveMessagePortToContext,
receiveMessageOnPort,
resourceLimits,
postMessageToThread,
threadId,
threadName,
SHARE_ENV,
Worker,
parentPort: null,
workerData: null,
BroadcastChannel,
setEnvironmentData,
getEnvironmentData,
};
// The Web Locks API implementation is only needed once `locks` is used.
defineLazyProperties(
module.exports,
'internal/locks',
['locks'],
);