From 35a01d9058fca2c4f5e9a4aa13a86d2eafc77c68 Mon Sep 17 00:00:00 2001 From: miga-heygen Date: Sun, 28 Jun 2026 14:36:21 +0000 Subject: [PATCH] perf(engine): reduce init overhead in headless capture sessions (#1718) Flush the GSAP proxy queue synchronously during capture session initialization and parallelize independent media/font/tailwind readiness waits. Closes #1715. Co-authored-by: Miguel Angel Simon Sierra --- packages/engine/src/services/frameCapture.ts | 157 +++++++++--------- .../src/generated/hf-early-stub-inline.ts | 2 +- packages/producer/stubs/hf-early-stub.ts | 11 ++ 3 files changed, 90 insertions(+), 80 deletions(-) diff --git a/packages/engine/src/services/frameCapture.ts b/packages/engine/src/services/frameCapture.ts index d9fe500f6..d6f81d0a2 100644 --- a/packages/engine/src/services/frameCapture.ts +++ b/packages/engine/src/services/frameCapture.ts @@ -990,6 +990,13 @@ export async function initializeSession(session: CaptureSession): Promise await gotoEntryPage(); logInitPhase("page.goto complete"); + // Flush the GSAP proxy queue synchronously instead of waiting for + // rAF-based batch ticks (100 ops/tick at ~16ms). In headless mode there's + // no UI responsiveness concern, so draining instantly eliminates the + // largest init-time cost for tween-heavy compositions. + await page.evaluate(`window.__hfFlushSync?.()`); + logInitPhase("GSAP proxy flush complete"); + const pageReadyTimeout = session.config?.playerReadyTimeout ?? DEFAULT_CONFIG.playerReadyTimeout; await pollHfReady(page, pageReadyTimeout); @@ -1001,24 +1008,37 @@ export async function initializeSession(session: CaptureSession): Promise await applyVideoMetadataHints(page, session.options.videoMetadataHints); logInitPhase("applyVideoMetadataHints complete"); - // Wait for all video elements to have decoded their CURRENT frame, not - // just metadata. readyState >= 2 (HAVE_CURRENT_DATA) means a frame is - // actually rasterized and ready to paint — at >= 1 (HAVE_METADATA) we - // only know the dimensions, and the first