Skip to content

Commit 2ac0177

Browse files
robertsLandoclaude
andcommitted
perf(sea): read SEA blob once and share buffer across targets
bake() previously reloaded the prep blob from disk per target inside Promise.all, causing N redundant reads and N peak buffer copies on multi-target builds. Read once before the loop and pass the shared Buffer into bake(). Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
1 parent beca977 commit 2ac0177

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

lib/sea.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ async function getNodejsExecutable(
311311
async function bake(
312312
nodePath: string,
313313
target: NodeTarget & Partial<Target>,
314-
blobPath: string,
314+
blobData: Buffer,
315315
) {
316316
const outPath = resolve(process.cwd(), target.output as string);
317317

@@ -343,7 +343,6 @@ async function bake(
343343
// This avoids two CI issues:
344344
// 1. "Text file busy" race condition from concurrent npx invocations
345345
// 2. "Argument is not a constructor" from npx downloading incompatible versions
346-
const blobData = await readFile(blobPath);
347346
await postjectInject(outPath, 'NODE_SEA_BLOB', blobData, {
348347
sentinelFuse: 'NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2',
349348
machoSegmentName: target.platform === 'macos' ? 'NODE_SEA' : undefined,
@@ -615,11 +614,15 @@ export async function seaEnhanced(
615614
pickBlobGeneratorBinary(minTargetMajor, nodePaths),
616615
);
617616

617+
// Read the blob once and share the buffer across all targets — avoids
618+
// N redundant disk reads and N peak buffer copies on multi-target builds.
619+
const blobData = await readFile(blobPath);
620+
618621
// Bake blob into each target executable
619622
await Promise.all(
620623
nodePaths.map(async (nodePath, i) => {
621624
const target = opts.targets[i];
622-
await bake(nodePath, target, blobPath);
625+
await bake(nodePath, target, blobData);
623626
await signMacOSIfNeeded(target.output!, target, opts.signature);
624627
}),
625628
);
@@ -661,10 +664,12 @@ export default async function sea(entryPoint: string, opts: SeaOptions) {
661664
pickBlobGeneratorBinary(resolveMinTargetMajor(opts.targets), nodePaths),
662665
);
663666

667+
const blobData = await readFile(blobPath);
668+
664669
await Promise.all(
665670
nodePaths.map(async (nodePath, i) => {
666671
const target = opts.targets[i];
667-
await bake(nodePath, target, blobPath);
672+
await bake(nodePath, target, blobData);
668673
await signMacOSIfNeeded(target.output!, target, opts.signature);
669674
}),
670675
);

0 commit comments

Comments
 (0)