Skip to content

0.7.0 init overhead causes ~2x capture_avg_ms regression vs 0.6.42 in headless server rendering #1653

Description

@yahelshiran-rvr

Describe the bug

After upgrading from @hyperframes/producer 0.6.42 to 0.7.0, capture_avg_ms roughly doubled at p50.
The per-frame capture path (prepareFrameForCapture) is byte-identical between versions ‚ the regression is new init-time work that runs inside the stage4Start ‚Date.now() timing window and gets amortized per frame.

The new init-time costs are:

  1. GSAP proxy queue draining via rAF (HF_EARLY_STUB_IIFE) ‚100 ops per tick at 33ms intervals, blocks readiness via __hfTimelinesBuilding
  2. __renderReady no longer set by bridge‚ duration getter returns 0 until runtime sets it after proxy drains, adding 100ms+ polling delay
  3. armStaticDedup verification‚ up to 400 seek+screenshot captures at init before any real frame is captured
  4. pollImagesReady + decodeAllImages‚ unconditional image readiness checks

These are all valuable features for browser/editor use. The issue is they run unconditionally in headless Puppeteer where the tradeoffs are different (no UI to keep responsive, short renders where init cost dominates).

Setting HF_STATIC_DEDUP_VERIFY=false improved p50 by ~16%. The remaining gap is primarily #1 and #2.

Link to reproduction

Steps to reproduce

  1. Render any template with @hyperframes/producer 0.6.42, note captureAvgMs from output
  2. Upgrade to 0.7.0, render the same template
  3. captureAvgMs is ~2x higher, uniform across all templates

Expected behavior

captureAvgMs should be comparable between 0.6.42 and 0.7.0 for the same template, since the per-frame capture code is unchanged.

Actual behavior

captureAvgMs doubled at p50 across all 39 benchmarked templates. In production (125-frame renders): pre-0.7.0 p50 ~153ms, post-0.7.0 p50 ~129ms (with HF_STATIC_DEDUP_VERIFY=false workaround, was higher before).

The metric includes init overhead because stage4Start = Date.now() is set before file server creation and session initialization, and captureMs = Date.now() - stage4Start captures everything.

Environment

✓ Version          0.7.0 
✓ Node.js          v22.16.0 (linux amd64)
✓ FFmpeg           ffmpeg version 5.1.9-0+deb12u1
✓ Chrome           Chromium 149.0.7827.53 (bundled: /usr/bin/chromium)

Additional context

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions