Skip to content

Bare data-composition-id hosts (static sections) burn the full player-ready budget on every render — contract question + API improvement request #3743

Description

@aikdna

Summary

A composition whose nested static section wrappers carry data-composition-id (but no data-composition-src) never registers a sub-composition timeline. As a result every render stalls for the full playerReadyTimeout (default 45 000 ms) at capture start, prints the "Sub-composition timelines not registered" warning, and then completes normally. We are not reporting a missing knob — the budget is configurable and works. This is a contract question plus an API improvement request.

Environment (pinned)

component version
hyperframes CLI 0.6.52 (npm, local node_modules/.bin/hyperframes)
Node.js 24.19.0
OS macOS 26.2 (25C56), Apple Silicon
Chrome (puppeteer-launched) 152.0.7977.76 (system Chrome via PUPPETEER_EXECUTABLE_PATH)
ffmpeg 8.1.2

Render command (topic tests add --no-browser-gpu where stated):

hyperframes render --format mp4 --quality standard --fps 30 --workers 1 --output out.mp4

Reproduction

Composition (~60 lines): root <div data-composition-id="root"> plus two nested section wrappers that carry data-composition-id ("alpha", "beta") without data-composition-src. The inline runtime registers only window.__timelines['root'] (GSAP-shaped seek/progress/duration API). A raw requestAnimationFrame() loop routes the render to screenshot capture with virtual time (as designed; lint WARN visible in logs).

Observed (4/4 default-budget runs, across GPU-default and --no-browser-gpu, small and 570-frame sizes): the render stalls for exactly playerReadyTimeout at capture start, then prints

[FrameCapture] Sub-composition timelines not registered after 45000ms: alpha, beta.
Compositions that load data asynchronously (e.g. fetch) must register window.__timelines[id] after setup completes.

and completes normally (rc=0).

Controls we ran

  • PRODUCER_PLAYER_READY_TIMEOUT_MS=1000 → identical warning after 1 s, render completes, end-to-end 11.9 s. The budget is configurable and the setting works.
  • Same page with alpha/beta also getting __timelines entries → no warning, no stall, end-to-end 9.2 s. The polled contract is literally "every [data-composition-id] host must register".

Questions / asks

  1. Is an id-tagged static section wrapper (no data-composition-src, content inlined, driven by the root timeline) a supported shape? From the bundle it looks like the first-class sub-composition contract is data-composition-src/-file hosts that are compiled-in and self-register; bare-id sections appear to be polled by the same gate.
  2. If static sections are supported, could they be exempted from pollSubCompositionTimelines (or opted out via a documented attribute) instead of costing the full player-ready budget on every render? In our production pipeline a 45 s/render penalty with a misleading "load data asynchronously" hint is the worst combination — the page is static and was never going to register.
  3. If they are not supported, a lint-level warning at compile time ("host X declares no source and registers no timeline; render will wait the full player-ready budget") would let producers fix this without reading dist/cli.js.

Package hygiene: full redacted logs available on request. Evidence logs were regenerated from raw output and verified by scan (0 remaining control bytes; no consumer-project paths, scene identifiers, or internal designations).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions