Skip to content

Simple video timeline probe step takes 10+ min, all real compositions time out immediately at 5% on low-memory hardware #1219

Closed

Description

@O1Anas

Describe the bug

On low-memory PCs (e.g. Intel i5, 8GB RAM, Linux), very simple compositions – a single <video> and a trivial GSAP timeline – will eventually render if you wait long enough (upwards of 10-20+ minutes), but any real/comprehensive composition (multiple scenes, dynamic JS) instantly fails at 5% ("Compiling composition") with a timeout, even when setting huge timeout env vars.

Example simple composition (see below):

  • Renders successfully after waiting a long time (initial 5% step takes 10+ minutes with no feedback/logs)
  • This proves engine is not totally broken on the system

Any real-world composition (even with big timeout settings):

  • Command:
    PRODUCER_PUPPETEER_PROTOCOL_TIMEOUT_MS=300000 PRODUCER_PLAYER_READY_TIMEOUT_MS=300000 PUPPETEER_PROTOCOL_TIMEOUT=300000 bunx hyperframes render videos/bliss_no_bliss -q draft -f 1 -w 1 --no-browser-gpu --browser-timeout=300
    
  • Fails instantly at 5% with:
    Failed: Runtime.callFunctionOn timed out. Increase the 'protocolTimeout' setting in launch/connect calls for a higher timeout if needed.
    Try --docker for containerized rendering
    
  • Setting all relevant protocol/socket/browser/hyperframes timeouts to huge values does not help

Steps to reproduce

  1. Try a trivial comp (the example HTML, see below):
    • It will render if you wait 10+ min with no logs after 5%
  2. Try any real timeline-driven comp (multi-scene, JS, etc.)
    • Always fails instantly at 5% probe, regardless of timeouts
  3. Even with maximum timeout settings, real comps do not start rendering at all

Minimal composition that will eventually work if you wait:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Mockup Video</title>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { background: red; overflow: hidden; }
    #stage { margin: auto; }
    video { width: 100%; height: 100%; object-fit: contain; }
  </style>
</head>
<body>
  <div id="stage" data-composition-id="mockup" data-width="1080" data-height="1920" data-start="0">
    <video id="mockup-video" muted playsinline data-track-index="0" data-start="0" data-duration="8"
      src="assets/mockup.webm"></video>
  </div>
  <script>
    window.__timelines = window.__timelines || {};
    window.__timelines['mockup'] = gsap.timeline({ paused: true });
  </script>
</body>
</html>

Expected behavior

  • Trivial comps should render quickly, with logs if slow
  • Real-world compositions should not time out at the duration probe/5% step, or should give actionable logging if stuck
  • Setting timeouts to huge values should let the probe try much longer before failing

Actual behavior

  • Trivial comp: hangs at 5% for minutes (10+), then eventually renders
  • Real comp: fails instantly at 5% with Protocol timeout error, no logs while waiting, even if all timeouts are huge

Environment

- Hyperframes 0.6.73 (latest)
- Node.js v22.22.2 (Linux x64)
- CPU: Intel i5-7200U quad-core
- RAM: 8GB (3GB free)
- Disk: 40+ GB free
- /dev/shm: 3.9GB
- Chrome headless 131.0.6778.85 (bundled)
- Docker: running/disabled (same effect)
- Lubuntu 24.04

Additional context

Activity

  1. self-assigned this
    on Jun 5, 2026
  2. O1Anas commented on Jun 5, 2026

    @O1Anas
    Author

    maybe, just maybe:

    Correction to the previous comment — the data-duration hypothesis was wrong

    I need to retract the previous comment. Setting data-duration on the root element does not fix the timeout — the hang persists identically. After reading the actual composition source, here is what I believe is actually happening:

    Root cause: SplitText blocking on unloaded Arabic font metrics

    The composition calls:

    new SplitText(".sentence", { type: "words", wordsClass: "word" });

    This runs synchronously on page load, before window.__timelines is registered. It targets .sentence elements that are visibility: hidden and contain Arabic text rendered with a custom @font-face font (Thmanyah, loaded from assets/fonts/...). On low-memory hardware, the font is not yet decoded when SplitText runs. SplitText internally reads offsetWidth/getBoundingClientRect on each word to split text — if the font hasn't painted, Chrome may block the layout thread waiting for the font to resolve, hanging the page indefinitely.

    Because window.__timelines["bliss_no_bliss"] is only registered after SplitText completes (it's inside a try block that runs after the split), hyperframes' window.__hf readiness probe via Runtime.callFunctionOn finds no registered timeline and waits until timeout.

    Things that confirm this:

    • Trivial composition (no custom font, no SplitText) → renders fine, just slow
    • Complex compositions → all fail at exactly 5%, regardless of media presence (videoCount:0, audioCount:0 confirmed), timeout env vars, or data-duration values
    • Both huwiyya-intro and bliss_no_bliss fail identically — both use Arabic @font-face + SplitText
    • The hang is always at the same probe step, never inside frame capture

    Proposed workarounds to test:

    1. Add font-display: swap or preload the font before SplitText runs:
    <link rel="preload" href="assets/fonts/thmanyahserifdisplay/thmanyahserifdisplay-Bold.woff2" as="font" type="font/woff2" crossorigin>
    1. Defer SplitText until fonts are confirmed loaded:
    document.fonts.ready.then(() => {
      new SplitText(".sentence", { type: "words", wordsClass: "word" });
      // ... rest of timeline build
      window.__timelines["bliss_no_bliss"] = tl;
    });

    Engine-level fix request: hyperframes should wait for document.fonts.ready before calling Runtime.callFunctionOn to probe window.__hf, or at minimum document that SplitText + unloaded custom fonts can deadlock the readiness probe on slow hardware.

  3. added 2 commits that reference this issue on Aug 6, 2026
    3808a56
    0abf5c1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions