Skip to content

Benchmarks & Stability

Ember Motion Studio is built for professional broadcast environments where failure is not an option. We measure performance not just in raw speed, but in absolute consistency and resilience. The DVGE engine guarantees that every single frame is frame-perfect.


Unlike real-time web engines, the DVGE engine does not use a system clock to calculate animations. Every frame is calculated purely from its discrete index (frame), making temporal drift structurally impossible.

Engine TypeTiming MethodResult under CPU Load
Traditional (GSAP / rAF)System clock (Date.now())Dropped frames under heavy CPU load
Ember (Frame-Math)Discrete frame index (ctx.frame)Identical output on any hardware

The engine doesn’t ask “how much time has passed?”. It asks “what does frame number X look like?”. The internal calculateTimeline(frame, fps, durationInFrames) function always produces the exact same result for the same input parameters, regardless of system load or hardware speed.

// Frame 45 of a 120-frame clip ALWAYS produces introProgress = 0.375
// On a 2015 laptop or a 2026 workstation. Without exception.
update: (ctx) => {
refs.title.style.opacity = ctx.timeline.introProgress; // Deterministic
}

The headless renderer operates with concurrency: 1 — one frame at a time — to guarantee the integrity of the alpha channel in every single frame. These benchmarks reflect this conservative, quality-first configuration.

Test Configuration:

  • Resolution: 1920×1080 @ 60 FPS
  • Codec: Apple ProRes 4444 (yuva444p10le, 10-bit)
  • Concurrency: 1 (by design, for strict alpha integrity)
  • Chromium: Headless mode with --force-cpu-rasterization
ComplexityClip DurationEstimated Export Time
Simple (Basic Lower Third, text + line)5 sec / 300 frames~2–4 seconds
Medium (News Ticker with scrolling, multiple items)10 sec / 600 frames~5–8 seconds
Complex (Data visualization, heavy CSS filters)15 sec / 900 frames~10–15 seconds

Times vary based on hardware. The dominating factor is Chromium’s headless rasterization speed, not the raw CPU of the system.


The auto-save system uses asynchronous atomic writes implemented in the core of Ember:

1. Change detected → 500ms debounce
2. Write to temporary file: project.json.tmp
3. Only if write is successful: fs.rename(tmp → project.json)
4. If process fails at any point: original project.json remains intact

Guarantee: An unexpected shutdown, power failure, or system crash during auto-saving will never corrupt your project file. The .tmp file is automatically discarded on the next boot.

The 500ms debounce is implemented directly in the Zustand store, batching rapid inspector changes before each disk write to minimize IO operations.


The plugin isolation system (Shadow DOM + fakeWindow Proxy) adds a critical layer of security with minimal performance impact:

ComponentImplementationImpact on 60fps loop
Shadow DOMattachShadow({ mode: 'open' })Negligible — native browser feature
fakeWindow ProxyIntercepts access to the real window< 0.1ms per frame
Polyfill getElementByIdshadowRoot.querySelector('#id')Equivalent to native
Total security overhead< 0.5ms per frame

The time window available for the 60fps preview loop is 16.6ms per frame. The sandbox overhead accounts for less than 3% of that budget.


Transparency Transformer — ProRes Alpha Channel

Section titled “Transparency Transformer — ProRes Alpha Channel”

Exporting with a pure alpha channel requires a three-layer chain to guarantee real transparency when dropped into DaVinci Resolve, Premiere Pro, or After Effects:

LayerImplementationPurpose
Chromium Flag--transparent-background-color=0Forces a transparent background in the headless process
JS InjectionevaluatePagebody.style.backgroundColor = 'transparent'Guarantees transparency before frame 0 is captured
Pixel Formatyuva444p10le (ProRes 4444, 10-bit)Preserves the full alpha channel in the final .mov file

The Frame 0 Fix resolves a critical bug where the first frame was captured before data hydration completed. The engine now leverages Remotion’s delayRender / continueRender to halt rendering until the plugin props are fully injected, guaranteeing the first exported frame is identical to the preview.


Data Probe Hydration — Windows CLI Limit Bypass

Section titled “Data Probe Hydration — Windows CLI Limit Bypass”

Windows imposes a strict limit of ~32,767 characters on command-line arguments. Passing serialized JSON data (like base64 images or heavy code blocks) via CLI caused silent truncation and render failures.

Implemented Solution:

Main Process → boots ephemeral HTTP server on localhost:[PORT]
RenderWrapper → fetch('http://localhost:[PORT]/props.json')
Remotion → receives the full payload with no size limit
Server → gracefully shuts down after render completes

This system bypasses the CLI character limit entirely and is completely transparent to the plugin developer.